@@ -241,8 +241,8 @@ func prepareRootfs(pipe *syncSocket, iConfig *initConfig) (err error) {
241241 // to the current root ("/"), and not to the old rootfs before it becomes "/". Applying the
242242 // flag in prepareRoot would affect the host mount namespace if the container's
243243 // root mount is shared.
244- // MS_PRIVATE is skipped as rootfsParentMountPrivate () is already called.
245- if config .RootPropagation != 0 && config .RootPropagation & unix .MS_PRIVATE == 0 {
244+ // MS_PRIVATE or MS_SLAVE is skipped as rootfsParentMountPropagation () is already called.
245+ if config .RootPropagation != 0 && config .RootPropagation & ( unix .MS_PRIVATE | unix . MS_SLAVE ) == 0 {
246246 if err := mount ("" , "/" , "" , uintptr (config .RootPropagation ), "" ); err != nil {
247247 return fmt .Errorf ("unable to apply root propagation flags: %w" , err )
248248 }
@@ -1061,19 +1061,27 @@ func mknodDevice(destDir *os.File, destName string, node *devices.Device) error
10611061 return nil
10621062}
10631063
1064- // rootfsParentMountPrivate ensures rootfs parent mount is private.
1064+ func rootfsParentMountPropagationFlags (rootPropagation int ) uintptr {
1065+ if rootPropagation & unix .MS_SLAVE != 0 {
1066+ return unix .MS_SLAVE
1067+ }
1068+ return unix .MS_PRIVATE
1069+ }
1070+
1071+ // rootfsParentMountPropagation ensures rootfs parent mount is not shared.
10651072// This is needed for two reasons:
10661073// - pivot_root() will fail if parent mount is shared;
1067- // - when we bind mount rootfs, if its parent is not private , the new mount
1074+ // - when we bind mount rootfs, if its parent is (r)shared , the new mount
10681075// will propagate (leak!) to parent namespace and we don't want that.
1069- func rootfsParentMountPrivate (path string ) error {
1076+ func rootfsParentMountPropagation (path string , rootPropagation int ) error {
10701077 var err error
1078+ flags := rootfsParentMountPropagationFlags (rootPropagation )
10711079 // Assuming path is absolute and clean (this is checked in
10721080 // libcontainer/validate). Any error other than EINVAL means we failed,
10731081 // and EINVAL means this is not a mount point, so traverse up until we
10741082 // find one.
10751083 for {
1076- err = unix .Mount ("" , path , "" , unix . MS_PRIVATE , "" )
1084+ err = unix .Mount ("" , path , "" , flags , "" )
10771085 if err == nil {
10781086 return nil
10791087 }
@@ -1083,9 +1091,9 @@ func rootfsParentMountPrivate(path string) error {
10831091 path = filepath .Dir (path )
10841092 }
10851093 return & mountError {
1086- op : "remount-private " ,
1094+ op : "remount-propagation " ,
10871095 target : path ,
1088- flags : unix . MS_PRIVATE ,
1096+ flags : flags ,
10891097 err : err ,
10901098 }
10911099}
@@ -1099,7 +1107,7 @@ func prepareRoot(config *configs.Config) error {
10991107 return err
11001108 }
11011109
1102- if err := rootfsParentMountPrivate (config .Rootfs ); err != nil {
1110+ if err := rootfsParentMountPropagation (config .Rootfs , config . RootPropagation ); err != nil {
11031111 return err
11041112 }
11051113
0 commit comments