2016-06-24 17:56:50 |
Seth Forshee |
description |
Consider the following,
root@dev:/tmp# mkdir foo
root@dev:/tmp# mount -t cgroup -o none,name=foo none foo
root@dev:/tmp# mkdir -p foo/bad
root@dev:/tmp# umount -l foo
root@dev:/tmp# mount -t cgroup -o none,name=foo none foo # hangs forever
^C
root@dev:/tmp# uname -a
Linux dev 4.4.0-22-generic #40-Ubuntu SMP Thu May 12 22:03:46 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
When I strace the mount task, I get a whole bunch of,
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
Which I think means that we're looping on,
https://github.com/torvalds/linux/blob/master/kernel/cgroup.c#L2137 |
SRU Justification
Impact: In some circumstances mount(2) of cgroup can endlessly return ERESTARTNOINTR, causing mount(8) to endlessly spin in loop.
Fix: Drop sauce patches for making cgroupfs work with s_user_ns in favor of patches from linux-next which do not have this problem.
Regression potential: The changes go beyond simply fixing the bug in order to sync up with upstream, but the upstream patches are by and large functionally equivalent. One consequence is that the bpf fs will no longer be mountable in a user namespace, but this fs is new in 4.4, unused as far as I can tell, and broken for user namespace mounts anyway.
---
Consider the following,
root@dev:/tmp# mkdir foo
root@dev:/tmp# mount -t cgroup -o none,name=foo none foo
root@dev:/tmp# mkdir -p foo/bad
root@dev:/tmp# umount -l foo
root@dev:/tmp# mount -t cgroup -o none,name=foo none foo # hangs forever
^C
root@dev:/tmp# uname -a
Linux dev 4.4.0-22-generic #40-Ubuntu SMP Thu May 12 22:03:46 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
When I strace the mount task, I get a whole bunch of,
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
mount("none", "/tmp/foo", "cgroup", MS_MGC_VAL, "none,name=foo") = ? ERESTARTNOINTR (To be restarted)
Which I think means that we're looping on,
https://github.com/torvalds/linux/blob/master/kernel/cgroup.c#L2137 |
|