diff --git a/mount/init.go b/mount/init.go index daec6ac8..a59b4a76 100644 --- a/mount/init.go +++ b/mount/init.go @@ -26,7 +26,7 @@ type mount struct { // InitializeMountNamespace sets up the devices, mount points, and filesystems for use inside a // new mount namespace. -func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) error { +func InitializeMountNamespace(rootfs, console string, sysReadonly bool, mountConfig *MountConfig) error { var ( err error flag = syscall.MS_PRIVATE @@ -40,7 +40,7 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) if err := syscall.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } - if err := mountSystem(rootfs, mountConfig); err != nil { + if err := mountSystem(rootfs, sysReadonly, mountConfig); err != nil { return fmt.Errorf("mount system %s", err) } if err := setupBindmounts(rootfs, mountConfig); err != nil { @@ -81,8 +81,8 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) // mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts // inside the mount namespace -func mountSystem(rootfs string, mountConfig *MountConfig) error { - for _, m := range newSystemMounts(rootfs, mountConfig.MountLabel, mountConfig.Mounts) { +func mountSystem(rootfs string, sysReadonly bool, mountConfig *MountConfig) error { + for _, m := range newSystemMounts(rootfs, mountConfig.MountLabel, sysReadonly, mountConfig.Mounts) { if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) { return fmt.Errorf("mkdirall %s %s", m.path, err) } @@ -192,14 +192,19 @@ func setupBindmounts(rootfs string, mountConfig *MountConfig) error { // TODO: this is crappy right now and should be cleaned up with a better way of handling system and // standard bind mounts allowing them to be more dynamic -func newSystemMounts(rootfs, mountLabel string, mounts Mounts) []mount { +func newSystemMounts(rootfs, mountLabel string, sysReadonly bool, mounts Mounts) []mount { systemMounts := []mount{ {source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags}, - {source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: defaultMountFlags}, {source: "tmpfs", path: filepath.Join(rootfs, "dev"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME, data: label.FormatMountLabel("mode=755", mountLabel)}, {source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1777,size=65536k", mountLabel)}, {source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)}, } + sysMountFlags := defaultMountFlags + if sysReadonly { + sysMountFlags |= syscall.MS_RDONLY + } + systemMounts = append(systemMounts, mount{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: sysMountFlags}) + return systemMounts } diff --git a/namespaces/init.go b/namespaces/init.go index 7c917c01..62452cba 100644 --- a/namespaces/init.go +++ b/namespaces/init.go @@ -76,6 +76,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn if err := mount.InitializeMountNamespace(rootfs, consolePath, + container.RestrictSys, (*mount.MountConfig)(container.MountConfig)); err != nil { return fmt.Errorf("setup mount namespace %s", err) } @@ -98,7 +99,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn // TODO: (crosbymichael) make this configurable at the Config level if container.RestrictSys { - if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus", "sys"); err != nil { + if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil { return err } }