@@ -187,10 +187,10 @@ func prepareTmp(topTmpDir string) (string, error) {
187187 if err != nil {
188188 return "" , err
189189 }
190- if err := mount (tmpdir , tmpdir , "" , " bind" , unix .MS_BIND , "" ); err != nil {
190+ if err := mount (tmpdir , tmpdir , "bind" , unix .MS_BIND , "" ); err != nil {
191191 return "" , err
192192 }
193- if err := mount ("" , tmpdir , "" , "" , uintptr (unix .MS_PRIVATE ), "" ); err != nil {
193+ if err := mount ("" , tmpdir , "" , uintptr (unix .MS_PRIVATE ), "" ); err != nil {
194194 return "" , err
195195 }
196196 return tmpdir , nil
@@ -262,7 +262,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
262262 if err := os .MkdirAll (subsystemPath , 0o755 ); err != nil {
263263 return err
264264 }
265- if err := utils .WithProcfd (c .root , b .Destination , func (procfd string ) error {
265+ if err := utils .WithProcfd (c .root , b .Destination , func (dstFD string ) error {
266266 flags := defaultMountFlags
267267 if m .Flags & unix .MS_RDONLY != 0 {
268268 flags = flags | unix .MS_RDONLY
@@ -275,7 +275,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
275275 data = cgroups .CgroupNamePrefix + data
276276 source = "systemd"
277277 }
278- return mount (source , b .Destination , procfd , "cgroup" , uintptr (flags ), data )
278+ return mountViaFDs (source , "" , b .Destination , dstFD , "cgroup" , uintptr (flags ), data )
279279 }); err != nil {
280280 return err
281281 }
@@ -306,8 +306,8 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
306306 if err := os .MkdirAll (dest , 0o755 ); err != nil {
307307 return err
308308 }
309- return utils .WithProcfd (c .root , m .Destination , func (procfd string ) error {
310- if err := mount (m .Source , m .Destination , procfd , "cgroup2" , uintptr (m .Flags ), m .Data ); err != nil {
309+ return utils .WithProcfd (c .root , m .Destination , func (dstFD string ) error {
310+ if err := mountViaFDs (m .Source , "" , m .Destination , dstFD , "cgroup2" , uintptr (m .Flags ), m .Data ); err != nil {
311311 // when we are in UserNS but CgroupNS is not unshared, we cannot mount cgroup2 (#2158)
312312 if errors .Is (err , unix .EPERM ) || errors .Is (err , unix .EBUSY ) {
313313 src := fs2 .UnifiedMountpoint
@@ -317,7 +317,7 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
317317 // the whole /sys/fs/cgroup.
318318 src = c .cgroup2Path
319319 }
320- err = mount (src , m .Destination , procfd , "" , uintptr (m .Flags )| unix .MS_BIND , "" )
320+ err = mountViaFDs (src , "" , m .Destination , dstFD , "" , uintptr (m .Flags )| unix .MS_BIND , "" )
321321 if c .rootlessCgroups && errors .Is (err , unix .ENOENT ) {
322322 err = nil
323323 }
@@ -358,15 +358,15 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
358358 }
359359 }()
360360
361- return utils .WithProcfd (rootfs , m .Destination , func (procfd string ) (Err error ) {
361+ return utils .WithProcfd (rootfs , m .Destination , func (dstFD string ) (Err error ) {
362362 // Copy the container data to the host tmpdir. We append "/" to force
363363 // CopyDirectory to resolve the symlink rather than trying to copy the
364364 // symlink itself.
365- if err := fileutils .CopyDirectory (procfd + "/" , tmpDir ); err != nil {
366- return fmt .Errorf ("tmpcopyup: failed to copy %s to %s (%s): %w" , m .Destination , procfd , tmpDir , err )
365+ if err := fileutils .CopyDirectory (dstFD + "/" , tmpDir ); err != nil {
366+ return fmt .Errorf ("tmpcopyup: failed to copy %s to %s (%s): %w" , m .Destination , dstFD , tmpDir , err )
367367 }
368368 // Now move the mount into the container.
369- if err := mount (tmpDir , m .Destination , procfd , "" , unix .MS_MOVE , "" ); err != nil {
369+ if err := mountViaFDs (tmpDir , "" , m .Destination , dstFD , "" , unix .MS_MOVE , "" ); err != nil {
370370 return fmt .Errorf ("tmpcopyup: failed to move mount: %w" , err )
371371 }
372372 return nil
@@ -665,8 +665,8 @@ func bindMountDeviceNode(rootfs, dest string, node *devices.Device) error {
665665 if f != nil {
666666 _ = f .Close ()
667667 }
668- return utils .WithProcfd (rootfs , dest , func (procfd string ) error {
669- return mount (node .Path , dest , procfd , "bind" , unix .MS_BIND , "" )
668+ return utils .WithProcfd (rootfs , dest , func (dstFD string ) error {
669+ return mountViaFDs (node .Path , "" , dest , dstFD , "bind" , unix .MS_BIND , "" )
670670 })
671671}
672672
@@ -763,7 +763,7 @@ func rootfsParentMountPrivate(rootfs string) error {
763763 // shared. Secondly when we bind mount rootfs it will propagate to
764764 // parent namespace and we don't want that to happen.
765765 if sharedMount {
766- return mount ("" , parentMount , "" , "" , unix .MS_PRIVATE , "" )
766+ return mount ("" , parentMount , "" , unix .MS_PRIVATE , "" )
767767 }
768768
769769 return nil
@@ -774,7 +774,7 @@ func prepareRoot(config *configs.Config) error {
774774 if config .RootPropagation != 0 {
775775 flag = config .RootPropagation
776776 }
777- if err := mount ("" , "/" , "" , "" , uintptr (flag ), "" ); err != nil {
777+ if err := mount ("" , "/" , "" , uintptr (flag ), "" ); err != nil {
778778 return err
779779 }
780780
@@ -785,13 +785,13 @@ func prepareRoot(config *configs.Config) error {
785785 return err
786786 }
787787
788- return mount (config .Rootfs , config .Rootfs , "" , " bind" , unix .MS_BIND | unix .MS_REC , "" )
788+ return mount (config .Rootfs , config .Rootfs , "bind" , unix .MS_BIND | unix .MS_REC , "" )
789789}
790790
791791func setReadonly () error {
792792 flags := uintptr (unix .MS_BIND | unix .MS_REMOUNT | unix .MS_RDONLY )
793793
794- err := mount ("" , "/" , "" , "" , flags , "" )
794+ err := mount ("" , "/" , "" , flags , "" )
795795 if err == nil {
796796 return nil
797797 }
@@ -800,7 +800,7 @@ func setReadonly() error {
800800 return & os.PathError {Op : "statfs" , Path : "/" , Err : err }
801801 }
802802 flags |= uintptr (s .Flags )
803- return mount ("" , "/" , "" , "" , flags , "" )
803+ return mount ("" , "/" , "" , flags , "" )
804804}
805805
806806func setupPtmx (config * configs.Config ) error {
@@ -858,7 +858,7 @@ func pivotRoot(rootfs string) error {
858858 // known to cause issues due to races where we still have a reference to a
859859 // mount while a process in the host namespace are trying to operate on
860860 // something they think has no mounts (devicemapper in particular).
861- if err := mount ("" , "." , "" , "" , unix .MS_SLAVE | unix .MS_REC , "" ); err != nil {
861+ if err := mount ("" , "." , "" , unix .MS_SLAVE | unix .MS_REC , "" ); err != nil {
862862 return err
863863 }
864864 // Perform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
@@ -907,7 +907,7 @@ func msMoveRoot(rootfs string) error {
907907 for _ , info := range mountinfos {
908908 p := info .Mountpoint
909909 // Be sure umount events are not propagated to the host.
910- if err := mount ("" , p , "" , "" , unix .MS_SLAVE | unix .MS_REC , "" ); err != nil {
910+ if err := mount ("" , p , "" , unix .MS_SLAVE | unix .MS_REC , "" ); err != nil {
911911 if errors .Is (err , unix .ENOENT ) {
912912 // If the mountpoint doesn't exist that means that we've
913913 // already blasted away some parent directory of the mountpoint
@@ -922,15 +922,15 @@ func msMoveRoot(rootfs string) error {
922922 } else {
923923 // If we have not privileges for umounting (e.g. rootless), then
924924 // cover the path.
925- if err := mount ("tmpfs" , p , "" , " tmpfs" , 0 , "" ); err != nil {
925+ if err := mount ("tmpfs" , p , "tmpfs" , 0 , "" ); err != nil {
926926 return err
927927 }
928928 }
929929 }
930930 }
931931
932932 // Move the rootfs on top of "/" in our mount namespace.
933- if err := mount (rootfs , "/" , "" , "" , unix .MS_MOVE , "" ); err != nil {
933+ if err := mount (rootfs , "/" , "" , unix .MS_MOVE , "" ); err != nil {
934934 return err
935935 }
936936 return chroot ()
@@ -968,7 +968,7 @@ func createIfNotExists(path string, isDir bool) error {
968968
969969// readonlyPath will make a path read only.
970970func readonlyPath (path string ) error {
971- if err := mount (path , path , "" , "" , unix .MS_BIND | unix .MS_REC , "" ); err != nil {
971+ if err := mount (path , path , "" , unix .MS_BIND | unix .MS_REC , "" ); err != nil {
972972 if errors .Is (err , os .ErrNotExist ) {
973973 return nil
974974 }
@@ -981,7 +981,7 @@ func readonlyPath(path string) error {
981981 }
982982 flags := uintptr (s .Flags ) & (unix .MS_NOSUID | unix .MS_NODEV | unix .MS_NOEXEC )
983983
984- if err := mount (path , path , "" , "" , flags | unix .MS_BIND | unix .MS_REMOUNT | unix .MS_RDONLY , "" ); err != nil {
984+ if err := mount (path , path , "" , flags | unix .MS_BIND | unix .MS_REMOUNT | unix .MS_RDONLY , "" ); err != nil {
985985 return err
986986 }
987987
@@ -1002,7 +1002,7 @@ func remountReadonly(m *configs.Mount) error {
10021002 // nosuid, etc.). So, let's use that case so that we can do
10031003 // this re-mount without failing in a userns.
10041004 flags |= unix .MS_REMOUNT | unix .MS_BIND | unix .MS_RDONLY
1005- if err := mount ("" , dest , "" , "" , uintptr (flags ), "" ); err != nil {
1005+ if err := mount ("" , dest , "" , uintptr (flags ), "" ); err != nil {
10061006 if errors .Is (err , unix .EBUSY ) {
10071007 time .Sleep (100 * time .Millisecond )
10081008 continue
@@ -1020,9 +1020,9 @@ func remountReadonly(m *configs.Mount) error {
10201020// For files, maskPath bind mounts /dev/null over the top of the specified path.
10211021// For directories, maskPath mounts read-only tmpfs over the top of the specified path.
10221022func maskPath (path string , mountLabel string ) error {
1023- if err := mount ("/dev/null" , path , "" , "" , unix .MS_BIND , "" ); err != nil && ! errors .Is (err , os .ErrNotExist ) {
1023+ if err := mount ("/dev/null" , path , "" , unix .MS_BIND , "" ); err != nil && ! errors .Is (err , os .ErrNotExist ) {
10241024 if errors .Is (err , unix .ENOTDIR ) {
1025- return mount ("tmpfs" , path , "" , " tmpfs" , unix .MS_RDONLY , label .FormatMountLabel ("" , mountLabel ))
1025+ return mount ("tmpfs" , path , "tmpfs" , unix .MS_RDONLY , label .FormatMountLabel ("" , mountLabel ))
10261026 }
10271027 return err
10281028 }
@@ -1037,28 +1037,28 @@ func writeSystemProperty(key, value string) error {
10371037}
10381038
10391039func remount (m * configs.Mount , rootfs string , mountFd * int ) error {
1040- source := m . Source
1040+ srcFD := ""
10411041 if mountFd != nil {
1042- source = "/proc/self/fd/" + strconv .Itoa (* mountFd )
1042+ srcFD = "/proc/self/fd/" + strconv .Itoa (* mountFd )
10431043 }
10441044
1045- return utils .WithProcfd (rootfs , m .Destination , func (procfd string ) error {
1045+ return utils .WithProcfd (rootfs , m .Destination , func (dstFD string ) error {
10461046 flags := uintptr (m .Flags | unix .MS_REMOUNT )
1047- err := mount ( source , m .Destination , procfd , m .Device , flags , "" )
1047+ err := mountViaFDs ( m . Source , srcFD , m .Destination , dstFD , m .Device , flags , "" )
10481048 if err == nil {
10491049 return nil
10501050 }
10511051 // Check if the source has ro flag...
10521052 var s unix.Statfs_t
1053- if err := unix .Statfs (source , & s ); err != nil {
1054- return & os.PathError {Op : "statfs" , Path : source , Err : err }
1053+ if err := unix .Statfs (m . Source , & s ); err != nil {
1054+ return & os.PathError {Op : "statfs" , Path : m . Source , Err : err }
10551055 }
10561056 if s .Flags & unix .MS_RDONLY != unix .MS_RDONLY {
10571057 return err
10581058 }
10591059 // ... and retry the mount with ro flag set.
10601060 flags |= unix .MS_RDONLY
1061- return mount ( source , m .Destination , procfd , m .Device , flags , "" )
1061+ return mountViaFDs ( m . Source , srcFD , m .Destination , dstFD , m .Device , flags , "" )
10621062 })
10631063}
10641064
@@ -1077,26 +1077,26 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string, mountFd
10771077 flags &= ^ unix .MS_RDONLY
10781078 }
10791079
1080+ srcFD := ""
1081+ if mountFd != nil {
1082+ srcFD = "/proc/self/fd/" + strconv .Itoa (* mountFd )
1083+ }
1084+
10801085 // Because the destination is inside a container path which might be
10811086 // mutating underneath us, we verify that we are actually going to mount
10821087 // inside the container with WithProcfd() -- mounting through a procfd
10831088 // mounts on the target.
1084- source := m .Source
1085- if mountFd != nil {
1086- source = "/proc/self/fd/" + strconv .Itoa (* mountFd )
1087- }
1088-
1089- if err := utils .WithProcfd (rootfs , m .Destination , func (procfd string ) error {
1090- return mount (source , m .Destination , procfd , m .Device , uintptr (flags ), data )
1089+ if err := utils .WithProcfd (rootfs , m .Destination , func (dstFD string ) error {
1090+ return mountViaFDs (m .Source , srcFD , m .Destination , dstFD , m .Device , uintptr (flags ), data )
10911091 }); err != nil {
10921092 return err
10931093 }
10941094 // We have to apply mount propagation flags in a separate WithProcfd() call
10951095 // because the previous call invalidates the passed procfd -- the mount
10961096 // target needs to be re-opened.
1097- if err := utils .WithProcfd (rootfs , m .Destination , func (procfd string ) error {
1097+ if err := utils .WithProcfd (rootfs , m .Destination , func (dstFD string ) error {
10981098 for _ , pflag := range m .PropagationFlags {
1099- if err := mount ("" , m .Destination , procfd , "" , uintptr (pflag ), "" ); err != nil {
1099+ if err := mountViaFDs ("" , "" , m .Destination , dstFD , "" , uintptr (pflag ), "" ); err != nil {
11001100 return err
11011101 }
11021102 }
0 commit comments