Skip to content

Commit d370e3c

Browse files
committed
libct: fix mounting via wrong proc fd
Due to a bug in commit 9c44407, when the user and mount namespaces are used, and the bind mount is followed by the cgroup mount in the spec, the cgroup is mounted using the bind mount's mount fd. This can be reproduced with podman 4.1 (when configured to use runc): $ podman run --uidmap 0:100:10000 quay.io/libpod/testimage:20210610 mount Error: /home/kir/git/runc/runc: runc create failed: unable to start container process: error during container init: error mounting "cgroup" to rootfs at "/sys/fs/cgroup": mount /proc/self/fd/11:/sys/fs/cgroup/systemd (via /proc/self/fd/12), flags: 0x20502f: operation not permitted: OCI permission denied or manually with the spec mounts containing something like this: { "destination": "/etc/resolv.conf", "type": "bind", "source": "/userdata/resolv.conf", "options": [ "bind" ] }, { "destination": "/sys/fs/cgroup", "type": "cgroup", "source": "cgroup", "options": [ "rprivate", "nosuid", "noexec", "nodev", "relatime", "ro" ] } The issue was not found earlier since it requires using userns, and even then mount fd is ignored by mountToRootfs, except for bind mounts, and all the bind mounts have mountfd set, except for the case of cgroup v1's /sys/fs/cgroup which is internally transformed into a bunch of bind mounts. This is a minimal fix for the issue, suitable for backporting. A test case is added which reproduces the issue without the fix applied. Fixes: 9c44407 ("Open bind mount sources from the host userns") Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 258eff1 commit d370e3c

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

libcontainer/rootfs_linux.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig, mountFds []int) (err
7373
// Therefore, we can access mountFds[i] without any concerns.
7474
if mountFds != nil && mountFds[i] != -1 {
7575
mountConfig.fd = &mountFds[i]
76+
} else {
77+
mountConfig.fd = nil
7678
}
7779

7880
if err := mountToRootfs(m, mountConfig); err != nil {

tests/integration/userns.bats

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,22 @@ function teardown() {
6464
runc exec test_busybox stat /tmp/mount-1/foo.txt /tmp/mount-2/foo.txt
6565
[ "$status" -eq 0 ]
6666
}
67+
68+
# Issue fixed by https://github.com/opencontainers/runc/pull/3510.
69+
@test "userns with bind mount before a cgroupfs mount" {
70+
# This can only be reproduced on cgroup v1 (and no cgroupns) due to the
71+
# way it is mounted in such case (a bunch of of bind mounts).
72+
requires cgroups_v1
73+
74+
# Add a bind mount right before the /sys/fs/cgroup mount,
75+
# and make sure cgroupns is not enabled.
76+
update_config ' .mounts |= map(if .destination == "/sys/fs/cgroup" then ({"source": "source-accessible/dir", "destination": "/tmp/mount-1", "options": ["bind"]}, .) else . end)
77+
| .linux.namespaces -= [{"type": "cgroup"}]'
78+
79+
runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
80+
[ "$status" -eq 0 ]
81+
82+
# Make sure this is real cgroupfs.
83+
runc exec test_busybox cat /sys/fs/cgroup/{pids,memory}/tasks
84+
[ "$status" -eq 0 ]
85+
}

0 commit comments

Comments
 (0)