@@ -28,13 +28,19 @@ import (
2828
2929const defaultMountFlags = unix .MS_NOEXEC | unix .MS_NOSUID | unix .MS_NODEV
3030
31+ // mountConfig contains mount data not specific to a mount point.
3132type mountConfig struct {
3233 root string
3334 label string
3435 cgroup2Path string
3536 rootlessCgroups bool
3637 cgroupns bool
37- fd * int
38+ }
39+
40+ // mountEntry contains mount data specific to a mount point.
41+ type mountEntry struct {
42+ * configs.Mount
43+ srcFD string
3844}
3945
4046// needsSetupDev returns true if /dev needs to be set up.
@@ -67,21 +73,20 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig, mountFds []int) (err
6773 rootlessCgroups : iConfig .RootlessCgroups ,
6874 cgroupns : config .Namespaces .Contains (configs .NEWCGROUP ),
6975 }
70- setupDev := needsSetupDev (config )
7176 for i , m := range config .Mounts {
77+ entry := mountEntry {Mount : m }
7278 // Just before the loop we checked that if not empty, len(mountFds) == len(config.Mounts).
7379 // Therefore, we can access mountFds[i] without any concerns.
7480 if mountFds != nil && mountFds [i ] != - 1 {
75- mountConfig .fd = & mountFds [i ]
76- } else {
77- mountConfig .fd = nil
81+ entry .srcFD = "/proc/self/fd/" + strconv .Itoa (mountFds [i ])
7882 }
7983
80- if err := mountToRootfs (m , mountConfig ); err != nil {
84+ if err := mountToRootfs (mountConfig , entry ); err != nil {
8185 return fmt .Errorf ("error mounting %q to rootfs at %q: %w" , m .Source , m .Destination , err )
8286 }
8387 }
8488
89+ setupDev := needsSetupDev (config )
8590 if setupDev {
8691 if err := createDevices (config ); err != nil {
8792 return fmt .Errorf ("error creating device nodes: %w" , err )
@@ -201,10 +206,10 @@ func cleanupTmp(tmpdir string) {
201206 _ = os .RemoveAll (tmpdir )
202207}
203208
204- func prepareBindMount (m * configs. Mount , rootfs string , mountFd * int ) error {
209+ func prepareBindMount (m mountEntry , rootfs string ) error {
205210 source := m .Source
206- if mountFd != nil {
207- source = "/proc/self/fd/" + strconv . Itoa ( * mountFd )
211+ if m . srcFD != "" {
212+ source = m . srcFD
208213 }
209214
210215 stat , err := os .Stat (source )
@@ -252,7 +257,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
252257 PropagationFlags : m .PropagationFlags ,
253258 }
254259
255- if err := mountToRootfs (tmpfs , c ); err != nil {
260+ if err := mountToRootfs (c , mountEntry { Mount : tmpfs } ); err != nil {
256261 return err
257262 }
258263
@@ -280,7 +285,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
280285 return err
281286 }
282287 } else {
283- if err := mountToRootfs (b , c ); err != nil {
288+ if err := mountToRootfs (c , mountEntry { Mount : b } ); err != nil {
284289 return err
285290 }
286291 }
@@ -328,7 +333,7 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
328333 })
329334}
330335
331- func doTmpfsCopyUp (m * configs. Mount , rootfs , mountLabel string ) (Err error ) {
336+ func doTmpfsCopyUp (m mountEntry , rootfs , mountLabel string ) (Err error ) {
332337 // Set up a scratch dir for the tmpfs on the host.
333338 tmpdir , err := prepareTmp ("/tmp" )
334339 if err != nil {
@@ -345,7 +350,7 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
345350 // m.Destination since we are going to mount *on the host*.
346351 oldDest := m .Destination
347352 m .Destination = tmpDir
348- err = mountPropagate (m , "/" , mountLabel , nil )
353+ err = mountPropagate (m , "/" , mountLabel )
349354 m .Destination = oldDest
350355 if err != nil {
351356 return err
@@ -373,10 +378,9 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
373378 })
374379}
375380
376- func mountToRootfs (m * configs. Mount , c * mountConfig ) error {
381+ func mountToRootfs (c * mountConfig , m mountEntry ) error {
377382 rootfs := c .root
378383 mountLabel := c .label
379- mountFd := c .fd
380384 dest , err := securejoin .SecureJoin (rootfs , m .Destination )
381385 if err != nil {
382386 return err
@@ -400,12 +404,12 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
400404 return err
401405 }
402406 // Selinux kernels do not support labeling of /proc or /sys
403- return mountPropagate (m , rootfs , "" , nil )
407+ return mountPropagate (m , rootfs , "" )
404408 case "mqueue" :
405409 if err := os .MkdirAll (dest , 0o755 ); err != nil {
406410 return err
407411 }
408- if err := mountPropagate (m , rootfs , "" , nil ); err != nil {
412+ if err := mountPropagate (m , rootfs , "" ); err != nil {
409413 return err
410414 }
411415 return label .SetFileLabel (dest , mountLabel )
@@ -420,7 +424,7 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
420424 if m .Extensions & configs .EXT_COPYUP == configs .EXT_COPYUP {
421425 err = doTmpfsCopyUp (m , rootfs , mountLabel )
422426 } else {
423- err = mountPropagate (m , rootfs , mountLabel , nil )
427+ err = mountPropagate (m , rootfs , mountLabel )
424428 }
425429
426430 if err != nil {
@@ -434,17 +438,17 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
434438 }
435439 return nil
436440 case "bind" :
437- if err := prepareBindMount (m , rootfs , mountFd ); err != nil {
441+ if err := prepareBindMount (m , rootfs ); err != nil {
438442 return err
439443 }
440- if err := mountPropagate (m , rootfs , mountLabel , mountFd ); err != nil {
444+ if err := mountPropagate (m , rootfs , mountLabel ); err != nil {
441445 return err
442446 }
443447 // bind mount won't change mount options, we need remount to make mount options effective.
444448 // first check that we have non-default options required before attempting a remount
445449 if m .Flags &^(unix .MS_REC | unix .MS_REMOUNT | unix .MS_BIND ) != 0 {
446450 // only remount if unique mount options are set
447- if err := remount (m , rootfs , mountFd ); err != nil {
451+ if err := remount (m , rootfs ); err != nil {
448452 return err
449453 }
450454 }
@@ -460,19 +464,19 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
460464 }
461465 case "cgroup" :
462466 if cgroups .IsCgroup2UnifiedMode () {
463- return mountCgroupV2 (m , c )
467+ return mountCgroupV2 (m . Mount , c )
464468 }
465- return mountCgroupV1 (m , c )
469+ return mountCgroupV1 (m . Mount , c )
466470 default :
467471 if err := checkProcMount (rootfs , dest , m .Source ); err != nil {
468472 return err
469473 }
470474 if err := os .MkdirAll (dest , 0o755 ); err != nil {
471475 return err
472476 }
473- return mountPropagate (m , rootfs , mountLabel , mountFd )
477+ return mountPropagate (m , rootfs , mountLabel )
474478 }
475- if err := setRecAttr (m , rootfs ); err != nil {
479+ if err := setRecAttr (m . Mount , rootfs ); err != nil {
476480 return err
477481 }
478482 return nil
@@ -1036,15 +1040,10 @@ func writeSystemProperty(key, value string) error {
10361040 return os .WriteFile (path .Join ("/proc/sys" , keyPath ), []byte (value ), 0o644 )
10371041}
10381042
1039- func remount (m * configs.Mount , rootfs string , mountFd * int ) error {
1040- srcFD := ""
1041- if mountFd != nil {
1042- srcFD = "/proc/self/fd/" + strconv .Itoa (* mountFd )
1043- }
1044-
1043+ func remount (m mountEntry , rootfs string ) error {
10451044 return utils .WithProcfd (rootfs , m .Destination , func (dstFD string ) error {
10461045 flags := uintptr (m .Flags | unix .MS_REMOUNT )
1047- err := mountViaFDs (m .Source , srcFD , m .Destination , dstFD , m .Device , flags , "" )
1046+ err := mountViaFDs (m .Source , m . srcFD , m .Destination , dstFD , m .Device , flags , "" )
10481047 if err == nil {
10491048 return nil
10501049 }
@@ -1058,13 +1057,13 @@ func remount(m *configs.Mount, rootfs string, mountFd *int) error {
10581057 }
10591058 // ... and retry the mount with ro flag set.
10601059 flags |= unix .MS_RDONLY
1061- return mountViaFDs (m .Source , srcFD , m .Destination , dstFD , m .Device , flags , "" )
1060+ return mountViaFDs (m .Source , m . srcFD , m .Destination , dstFD , m .Device , flags , "" )
10621061 })
10631062}
10641063
10651064// Do the mount operation followed by additional mounts required to take care
10661065// of propagation flags. This will always be scoped inside the container rootfs.
1067- func mountPropagate (m * configs. Mount , rootfs string , mountLabel string , mountFd * int ) error {
1066+ func mountPropagate (m mountEntry , rootfs string , mountLabel string ) error {
10681067 var (
10691068 data = label .FormatMountLabel (m .Data , mountLabel )
10701069 flags = m .Flags
@@ -1077,17 +1076,12 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string, mountFd
10771076 flags &= ^ unix .MS_RDONLY
10781077 }
10791078
1080- srcFD := ""
1081- if mountFd != nil {
1082- srcFD = "/proc/self/fd/" + strconv .Itoa (* mountFd )
1083- }
1084-
10851079 // Because the destination is inside a container path which might be
10861080 // mutating underneath us, we verify that we are actually going to mount
10871081 // inside the container with WithProcfd() -- mounting through a procfd
10881082 // mounts on the target.
10891083 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 )
1084+ return mountViaFDs (m .Source , m . srcFD , m .Destination , dstFD , m .Device , uintptr (flags ), data )
10911085 }); err != nil {
10921086 return err
10931087 }
0 commit comments