namespace-util: Merge namespace_enter_delegated() into namespace_enter()

There's no need to pass in a boolean to decide whether we use
namespace_enter_delegated() or not. Instead, we can just check if we
have CAP_SYS_ADMIN in our own user namespace. If we don't, then we have
to insist on a child user namespace being passed in and we have to enter
it first to get CAP_SYS_ADMIN as without CAP_SYS_ADMIN we wouldn't be able
to call setns() in the first place. If we do have CAP_SYS_ADMIN, we can
always enter the other namespaces first before entering the user namespace.

Additionally, we don't fail anymore if we can't reset the UID/GID since a
root user might not always be available in every user namespace we might
enter.
This commit is contained in:
Daan De Meyer
2026-02-16 10:27:02 +01:00
parent e2c1f3ca2a
commit 211c3c9d41
7 changed files with 97 additions and 66 deletions
+1 -5
View File
@@ -1778,7 +1778,6 @@ int namespace_fork_full(
int netns_fd,
int userns_fd,
int root_fd,
bool delegated,
PidRef *ret) {
_cleanup_(pidref_done_sigkill_wait) PidRef pidref_outer = PIDREF_NULL;
@@ -1824,10 +1823,7 @@ int namespace_fork_full(
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
if (delegated)
r = namespace_enter_delegated(userns_fd, pidns_fd, mntns_fd, netns_fd, root_fd);
else
r = namespace_enter(pidns_fd, mntns_fd, netns_fd, userns_fd, root_fd);
r = namespace_enter(pidns_fd, mntns_fd, netns_fd, userns_fd, root_fd);
if (r < 0) {
log_full_errno(prio, r, "Failed to join namespace: %m");
report_errno_and_exit(errno_pipe_fd[1], r);