Initially mount /sys as ro instead of remount

The issue with doing a remount as ro with sysfs is that if a container
is still in one of the hosts namepsaces, commonly with the NET
namespace, the remount will cause the host's systems sysfs to be
remounted as ro also.  We can fix this correctly by not doing the
remount and just mount sys as ro in the first place.

The other remounts are individual files within proc so they will not
have this issue.

For context please see:
https://github.com/dotcloud/docker/issues/7101
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@docker.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-07-18 14:13:38 -07:00
parent 2e422fc2a1
commit 0dcae82acb
2 changed files with 13 additions and 7 deletions

View File

@ -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
}

View File

@ -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
}
}