restore: move cgroup restore after creds are prepared

prepare_cgroup_namespace() can call userns_call() to move
the task into a cgroup. userns_call() uses
sendmsg() with SCM_CREDENTIALS to communicate with usernsd.

If the user namespace maps are configured such that the parent's UID
(typically 0) is not mapped to the same UID in the child namespace
(i.e., lower_first != 0), the getuid() syscall in the child will return
the overflow UID (65534) until the child's credentials are explicitly
set within the namespace.

When sendmsg() is called with SCM_CREDENTIALS containing the overflow UID,
the kernel's __scm_send function returns -EINVAL, causing the restore
to fail.

[avagin: tweaked the commit message]
Signed-off-by: Efim Verzakov <efimverzakov@gmail.com>
Signed-off-by: Andrei Vagin <avagin@gmail.com>
This commit is contained in:
Efim Verzakov 2026-02-20 14:10:01 +00:00 committed by Andrei Vagin
parent 1a4b338eda
commit f22c95d2d9

View file

@ -1572,7 +1572,12 @@ static int __restore_task_with_children(void *_arg)
/* Wait prepare_userns */
if (restore_finish_ns_stage(CR_STATE_ROOT_TASK, CR_STATE_PREPARE_NAMESPACES) < 0)
goto err;
}
if (needs_prep_creds(current) && (prepare_userns_creds()))
goto err;
if (current->parent == NULL) {
/*
* Since we don't support nesting of cgroup namespaces, let's
* only set up the cgns (if it exists) in the init task.
@ -1581,9 +1586,6 @@ static int __restore_task_with_children(void *_arg)
goto err;
}
if (needs_prep_creds(current) && (prepare_userns_creds()))
goto err;
/*
* Call this _before_ forking to optimize cgroups
* restore -- if all tasks live in one set of cgroups