[CRIU] [PATCH v1 14/17] user_ns: setup arguments for restorer

Kirill Tkhai ktkhai at virtuozzo.com
Thu Jan 12 09:54:24 PST 2017


Tell restorer, which user_ns manipulation should it do.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/cr-restore.c       |   50 +++++++++++++++++++++++++++++++++++++++++++++++
 criu/include/restorer.h |    2 ++
 2 files changed, 52 insertions(+)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 296742ef5..a6f70ff93 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -2605,6 +2605,54 @@ static int signal_to_mem(SiginfoEntry *sie)
 	return 0;
 }
 
+static int setup_userns_args(struct task_restore_args *args)
+{
+	struct user_ns_state *ptr;
+	struct rst_user_ns *rst;
+	struct ns_id *ns;
+	int i;
+
+	args->setns_user_ns = NULL;
+	args->unshare_user_ns = NULL;
+
+	if (!current->ids->has_user_ns_id)
+		return 0;
+
+	ns = lookup_ns_by_id(current->ids->user_ns_id, &user_ns_desc);
+	if (!ns) {
+		pr_err("Can't find user_ns\n");
+		return -1;
+	}
+
+	ptr = rst_mem_remap_ptr(user_ns_states_pos, RM_SHREMAP);
+
+	if (ns->type == NS_OTHER) {
+		if (ns->ns_pid == current->pid.virt) {
+			/* We should create this user_ns */
+			args->unshare_user_ns = ptr + (ns->user.rst_state - user_ns_states);
+			if (ns->parent->type == NS_OTHER) {
+				/* Switch to parent user_ns before */
+				args->setns_user_ns = ptr + (ns->parent->user.rst_state - user_ns_states);
+			}
+		} else {
+			/* Borrow user_ns from its owner */
+			args->setns_user_ns = ptr + (ns->user.rst_state - user_ns_states);
+		}
+	}
+
+	if (args->child_user_ns_n) {
+		RST_MEM_FIXUP_PPTR(args->child_user_ns);
+		rst = args->child_user_ns;
+
+		for (i = 0; i < args->child_user_ns_n; i++) {
+			rst->st = ptr + (rst->st - user_ns_states);
+			rst += sizeof(*rst) + (rst->uid_map_size + rst->gid_map_size);
+		}
+	}
+
+	return 0;
+}
+
 static int open_signal_image(int type, pid_t pid, unsigned int *nr)
 {
 	int ret;
@@ -3085,6 +3133,8 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
 
 	strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm));
 
+	if (setup_userns_args(task_args) < 0)
+		return -1;
 	/*
 	 * Fill up per-thread data.
 	 */
diff --git a/criu/include/restorer.h b/criu/include/restorer.h
index ac3707d26..4c48d2054 100644
--- a/criu/include/restorer.h
+++ b/criu/include/restorer.h
@@ -152,6 +152,8 @@ struct task_restore_args {
 
 	struct rst_user_ns		*child_user_ns;
 	unsigned int			child_user_ns_n;
+	struct user_ns_state		*setns_user_ns;
+	struct user_ns_state		*unshare_user_ns;
 
 	/* * * * * * * * * * * * * * * * * * * * */
 



More information about the CRIU mailing list