@@ -306,26 +306,41 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
306
306
if err := os .MkdirAll (dest , 0o755 ); err != nil {
307
307
return err
308
308
}
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 {
311
- // when we are in UserNS but CgroupNS is not unshared, we cannot mount cgroup2 (#2158)
312
- if errors .Is (err , unix .EPERM ) || errors .Is (err , unix .EBUSY ) {
313
- src := fs2 .UnifiedMountpoint
314
- if c .cgroupns && c .cgroup2Path != "" {
315
- // Emulate cgroupns by bind-mounting
316
- // the container cgroup path rather than
317
- // the whole /sys/fs/cgroup.
318
- src = c .cgroup2Path
319
- }
320
- err = mount (src , m .Destination , procfd , "" , uintptr (m .Flags )| unix .MS_BIND , "" )
321
- if c .rootlessCgroups && errors .Is (err , unix .ENOENT ) {
322
- err = nil
323
- }
324
- }
325
- return err
326
- }
327
- return nil
309
+ err = utils .WithProcfd (c .root , m .Destination , func (procfd string ) error {
310
+ return mount (m .Source , m .Destination , procfd , "cgroup2" , uintptr (m .Flags ), m .Data )
328
311
})
312
+ if err == nil || ! (errors .Is (err , unix .EPERM ) || errors .Is (err , unix .EBUSY )) {
313
+ return err
314
+ }
315
+
316
+ // When we are in UserNS but CgroupNS is not unshared, we cannot mount
317
+ // cgroup2 (#2158), so fall back to bind mount.
318
+ bindM := & configs.Mount {
319
+ Device : "bind" ,
320
+ Source : fs2 .UnifiedMountpoint ,
321
+ Destination : m .Destination ,
322
+ Flags : unix .MS_BIND | m .Flags ,
323
+ PropagationFlags : m .PropagationFlags ,
324
+ }
325
+ if c .cgroupns && c .cgroup2Path != "" {
326
+ // Emulate cgroupns by bind-mounting the container cgroup path
327
+ // rather than the whole /sys/fs/cgroup.
328
+ bindM .Source = c .cgroup2Path
329
+ }
330
+ // mountToRootfs() handles remounting for MS_RDONLY.
331
+ // No need to set c.fd here, because mountToRootfs() calls utils.WithProcfd() by itself in mountPropagate().
332
+ err = mountToRootfs (bindM , c )
333
+ if c .rootlessCgroups && errors .Is (err , unix .ENOENT ) {
334
+ // ENOENT (for `src = c.cgroup2Path`) happens when rootless runc is being executed
335
+ // outside the userns+mountns.
336
+ //
337
+ // Mask `/sys/fs/cgroup` to ensure it is read-only, even when `/sys` is mounted
338
+ // with `rbind,ro` (`runc spec --rootless` produces `rbind,ro` for `/sys`).
339
+ err = utils .WithProcfd (c .root , m .Destination , func (procfd string ) error {
340
+ return maskPath (procfd , c .label )
341
+ })
342
+ }
343
+ return err
329
344
}
330
345
331
346
func doTmpfsCopyUp (m * configs.Mount , rootfs , mountLabel string ) (Err error ) {
0 commit comments