userns: detect initial namespace by inode - #240
Conversation
| "syscall" | ||
| ) | ||
|
|
||
| const procUserInitIno = 0xEFFFFFFD |
There was a problem hiding this comment.
Could you add a comment line to refer to https://github.com/torvalds/linux/blob/v7.1/include/uapi/linux/nsfs.h#L50
3a4e7f4 to
372f6db
Compare
The current uid_map heuristic treats a private user namespace with an identity uid_map as the initial user namespace. systemd 260 can create that shape with PrivateUsers=full, causing callers to believe they can perform initial-namespace-only operations such as cgroup device BPF setup. Use /proc/self/ns/user's inode instead and compare it with the kernel's PROC_USER_INIT_INO value. This detects the initial user namespace directly instead of inferring it from the uid_map layout. Related: containers/crun#2150 Signed-off-by: Alvaro Leiva Geisse <aleivag@gmail.com>
kolyshkin
left a comment
There was a problem hiding this comment.
-
I think that
TestInodeInUserNS(and a separatefunc inodeInUserNS) makes little sense now when the code is very simple and clean. I mean, we just do stat(2) and comparest.Ino-- this needs no unit tests. -
The problem is, this (predefined inode number for
PROC_USER_INIT_INO) only appears in kernel v3.8 (it comes from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=98f842e675f9), and since Go itself (since Go 1.24) requires kernel v3.2 (see https://go.dev/wiki/MinimumRequirements#linuxlinux), we do need a fallback to old code. It will still work since most people run linux >= v3.8, and no one sane will run systemd v260+ on an older kernel.
Note this package (github.com/moby/sys/userns) only requires Go 1.18 which itself has a lower linux kernel version requirement. Meaning, we definitely need the fallback. |
372f6db to
41c4209
Compare
kolyshkin
left a comment
There was a problem hiding this comment.
See my comments above
The current uid_map heuristic treats a private user namespace with an identity uid_map as the initial user namespace. systemd 260 can create that shape with PrivateUsers=full, causing callers to believe they can perform initial-namespace-only operations such as cgroup device BPF setup.
Use /proc/self/ns/user's inode instead and compare it with the kernel's PROC_USER_INIT_INO value. This detects the initial user namespace directly instead of inferring it from the uid_map layout.
Related: #239