[CRIU] [PATCH v1 16/17] restorer: Move uids/gids assignment above setns() and unshare()
Kirill Tkhai
ktkhai at virtuozzo.com
Thu Jan 12 09:54:40 PST 2017
Since uids/gids may do not have a mapping in task's current
user namespace, we set them in NS_ROOT, and they will sanely
appeared in the whole hierarhy.
It seems there will no problems with seccomp assignment,
as after xids restore the task still have CAP_SYS_ADMIN
permittions.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/pie/restorer.c | 138 ++++++++++++++++++++++++++++-----------------------
1 file changed, 77 insertions(+), 61 deletions(-)
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index 2b8ba3074..7c82a69cd 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -153,7 +153,7 @@ static int lsm_set_label(char *label, int procfd)
return 0;
}
-static int restore_creds(struct thread_creds_args *args, int procfd)
+static int restore_caps(struct thread_creds_args *args, int procfd)
{
CredsEntry *ce = &args->creds;
int b, i, ret;
@@ -161,62 +161,6 @@ static int restore_creds(struct thread_creds_args *args, int procfd)
struct cap_data data[_LINUX_CAPABILITY_U32S_3];
/*
- * We're still root here and thus can do it without failures.
- */
-
- /*
- * Setup supplementary group IDs early.
- */
- if (args->groups) {
- ret = sys_setgroups(ce->n_groups, args->groups);
- if (ret) {
- pr_err("Can't setup supplementary group IDs: %d\n", ret);
- return -1;
- }
- }
-
- /*
- * First -- set the SECURE_NO_SETUID_FIXUP bit not to
- * lose caps bits when changing xids.
- */
-
- ret = sys_prctl(PR_SET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP, 0, 0, 0);
- if (ret) {
- pr_err("Unable to set SECURE_NO_SETUID_FIXUP: %d\n", ret);
- return -1;
- }
-
- /*
- * Second -- restore xids. Since we still have the CAP_SETUID
- * capability nothing should fail. But call the setfsXid last
- * to override the setresXid settings.
- */
-
- ret = sys_setresuid(ce->uid, ce->euid, ce->suid);
- if (ret) {
- pr_err("Unable to set real, effective and saved user ID: %d\n", ret);
- return -1;
- }
-
- sys_setfsuid(ce->fsuid);
- if (sys_setfsuid(-1) != ce->fsuid) {
- pr_err("Unable to set fsuid\n");
- return -1;
- }
-
- ret = sys_setresgid(ce->gid, ce->egid, ce->sgid);
- if (ret) {
- pr_err("Unable to set real, effective and saved group ID: %d\n", ret);
- return -1;
- }
-
- sys_setfsgid(ce->fsgid);
- if (sys_setfsgid(-1) != ce->fsgid) {
- pr_err("Unable to set fsgid\n");
- return -1;
- }
-
- /*
* Third -- restore securebits. We don't need them in any
* special state any longer.
*/
@@ -427,6 +371,70 @@ static int restore_seccomp(struct task_restore_args *args)
return -1;
}
+static int restore_xids(struct thread_creds_args *args, int procfd)
+{
+ CredsEntry *ce = &args->creds;
+ int ret;
+
+ /*
+ * We're still root here and thus can do it without failures.
+ */
+
+ /*
+ * Setup supplementary group IDs early.
+ */
+ if (args->groups) {
+ ret = sys_setgroups(ce->n_groups, args->groups);
+ if (ret) {
+ pr_err("Can't setup supplementary group IDs: %d\n", ret);
+ return -1;
+ }
+ }
+
+ /*
+ * First -- set the SECURE_NO_SETUID_FIXUP bit not to
+ * lose caps bits when changing xids.
+ */
+
+ ret = sys_prctl(PR_SET_SECUREBITS, 1 << SECURE_NO_SETUID_FIXUP, 0, 0, 0);
+ if (ret) {
+ pr_err("Unable to set SECURE_NO_SETUID_FIXUP: %d\n", ret);
+ return -1;
+ }
+
+ /*
+ * Second -- restore xids. Since we still have the CAP_SETUID
+ * capability nothing should fail. But call the setfsXid last
+ * to override the setresXid settings.
+ */
+
+ ret = sys_setresuid(ce->uid, ce->euid, ce->suid);
+ if (ret) {
+ pr_err("Unable to set real, effective and saved user ID: %d\n", ret);
+ return -1;
+ }
+
+ sys_setfsuid(ce->fsuid);
+ if (sys_setfsuid(-1) != ce->fsuid) {
+ pr_err("Unable to set fsuid\n");
+ return -1;
+ }
+
+ ret = sys_setresgid(ce->gid, ce->egid, ce->sgid);
+ if (ret) {
+ pr_err("Unable to set real, effective and saved group ID: %d\n", ret);
+ return -1;
+ }
+
+ sys_setfsgid(ce->fsgid);
+ if (sys_setfsgid(-1) != ce->fsgid) {
+ pr_err("Unable to set fsgid\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int restore_thread_common(struct thread_restore_args *args)
{
sys_set_tid_address((int *)decode_pointer(args->clear_tid_addr));
@@ -488,7 +496,10 @@ long __export_restore_thread(struct thread_restore_args *args)
if (restore_thread_common(args))
goto core_restore_end;
- ret = restore_creds(args->creds_args, args->ta->proc_fd);
+ ret = restore_xids(args->creds_args, args->ta->proc_fd);
+ if (ret)
+ goto core_restore_end;
+ ret = restore_caps(args->creds_args, args->ta->proc_fd);
if (ret)
goto core_restore_end;
@@ -1456,6 +1467,10 @@ long __export_restore_task(struct task_restore_args *args)
if (ret)
goto core_restore_end;
+ ret = restore_xids(args->t->creds_args, args->proc_fd);
+ if (ret)
+ goto core_restore_end;
+
if (args->setns_user_ns) {
futex_wait_while_lt(&args->setns_user_ns->futex, USER_NS__CREATED);
ret = restorer_set_user_ns(args->proc_fd, args->setns_user_ns->ns_pid);
@@ -1626,8 +1641,9 @@ long __export_restore_task(struct task_restore_args *args)
rst_tcp_socks_all(args);
- /* The kernel restricts setting seccomp to uid 0 in the current user
- * ns, so we must do this before restore_creds.
+ /*
+ * The kernel restricts setting seccomp to CAP_SYS_ADMIN the current user
+ * ns, so we must do this before restore_caps().
*/
pr_info("restoring seccomp mode %d for %ld\n", args->seccomp_mode, sys_getpid());
if (restore_seccomp(args))
@@ -1638,7 +1654,7 @@ long __export_restore_task(struct task_restore_args *args)
* turning off TCP repair is CAP_SYS_NED_ADMIN protected,
* thus restore* creds _after_ all of the above.
*/
- ret = restore_creds(args->t->creds_args, args->proc_fd);
+ ret = restore_caps(args->t->creds_args, args->proc_fd);
ret = ret || restore_dumpable_flag(&args->mm);
ret = ret || restore_pdeath_sig(args->t);
More information about the CRIU
mailing list