utils: fall back to uid_map on OpenVZ - #2233
Conversation
thaJeztah
left a comment
There was a problem hiding this comment.
Thx! I'm not very fluent in C, so only some things that stood out 😅 (perhaps @kolyshkin can give it a peek)
| /* OpenVZ virtualizes the namespace inode numbers exposed through procfs, so | ||
| PROC_USER_INIT_INO cannot reliably identify the initial user namespace | ||
| there. */ | ||
| if (running_in_openvz ()) |
There was a problem hiding this comment.
Not sure if very relevant; in moby/sys, I opted to add a happy-path before falling back to detecting OpenVZ; that was mostly to avoid doing the extra work for a niche case (OpenVZ);
// The kernel's initial user namespace inode is definitive when it
// matches. OpenVZ virtualizes namespace inode numbers, so a mismatch
// must fall back to uid_map-based detection there.
if st.Ino == procUserInitIno {
return false
}
if runningInOpenVZ() {
return runningInUserNSFromUIDMap()
}
return trueThere was a problem hiding this comment.
thanks, that is better! Fixed now
There was a problem hiding this comment.
@giuseppe this might make sense; alas my openvz installation's kernel is too old to have proper userns so I can't test this but purely theoretically it looks fine.
| return ret; | ||
| } | ||
|
|
||
| return strstr (buffer, "4294967295") ? 0 : 1; |
There was a problem hiding this comment.
Also (comparing with moby/sys); looks like we parse the columns, and compare all (instead of only matching the magic value); probably in practice wouldn't make a difference (?);
// As per user_namespaces(7), /proc/self/uid_map of
// the initial user namespace shows 0 0 4294967295.
initNS := a == 0 && b == 0 && c == 4294967295
return !initNSThere was a problem hiding this comment.
I thought about it, too, but the crun code was always like this (strstr (buffer, "4294967295") ? 0 : 1) so I guess comparing all three numbers are excessive.
There was a problem hiding this comment.
I've used strstr (buffer, "4294967295") ? 0 : 1 because the 4294967295 value can be used only with the full mapping and it can't be the initial ID because the mappings need to have at least one ID
01d73dd to
3a67f86
Compare
|
One other (unrelated to openvz, related to #2151) thing is, kernels < 3.8 don't have Unless, of course, we don't support kernels < 3.8 (frankly I dunno if we do). |
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Commit d73e66c ("utils: detect initial user namespace by inode") changed check_running_in_user_namespace() to compare the inode of /proc/self/ns/user against PROC_USER_INIT_INO, so that a user namespace with a full identity mapping -- such as the one systemd >= 260 sets up for PrivateUsers=full -- is no longer mistaken for the initial one. OpenVZ virtualizes the namespace inode numbers it exposes through procfs, so PROC_USER_INIT_INO does not identify the initial user namespace there and the new check regressed the detection inside OpenVZ containers. This was reported for moby, which made the same change, by Sebastiaan van Stijn in containers#2150, along with the suggestion to special-case OpenVZ the way moby/sys#255 does: moby/sys#255 Detect OpenVZ with the same procfs test systemd uses -- /proc/vz is exposed both on the host and inside a container, /proc/bc only on the host -- and fall back to the uid_map heuristic there. The inode check stays the preferred path everywhere else. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Commit d73e66c ("utils: detect initial user namespace by inode") took a missing /proc/self/ns/user to mean that the kernel does not support user namespaces at all. The file was added in Linux 3.8, and kernels older than that can still be in a user namespace, which /proc/self/uid_map does describe. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
ok this was easy to fix, so I've added a patch. |
3a67f86 to
2f58fd6
Compare
Commit d73e66c ("utils: detect initial user namespace by inode") changed check_running_in_user_namespace() to compare the inode of /proc/self/ns/user against PROC_USER_INIT_INO, so that a user namespace with a full identity mapping -- such as the one systemd >= 260 sets up for PrivateUsers=full -- is no longer mistaken for the initial one.
OpenVZ virtualizes the namespace inode numbers it exposes through procfs, so PROC_USER_INIT_INO does not identify the initial user namespace there and the new check regressed the detection inside OpenVZ containers. This was reported for moby, which made the same change, by Sebastiaan van Stijn in #2150, along with the suggestion to special-case OpenVZ the way moby/sys#255 does:
moby/sys#255
Detect OpenVZ with the same procfs test systemd uses -- /proc/vz is exposed both on the host and inside a container, /proc/bc only on the host -- and fall back to the uid_map heuristic there. The inode check stays the preferred path everywhere else.