[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