[CRIU] [PATCH v4 06/31] user_ns: Make collect_user_ns() allocate child UsernsEntry mappings

Kirill Tkhai ktkhai at virtuozzo.com
Wed Feb 22 03:31:21 PST 2017


Allocate mapping for NS_OTHER too.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/include/namespaces.h |    4 +++
 criu/namespaces.c         |   60 +++++++++++++++++++++++++++++++++------------
 2 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h
index 1b5409aef..642f04cf9 100644
--- a/criu/include/namespaces.h
+++ b/criu/include/namespaces.h
@@ -6,6 +6,7 @@
 #include "common/compiler.h"
 #include "files.h"
 #include "common/list.h"
+#include "images/userns.pb-c.h"
 
 #ifndef CLONE_NEWNS
 #define CLONE_NEWNS	0x00020000
@@ -112,6 +113,9 @@ struct ns_id {
 			int nlsk;	/* for sockets collection */
 			int seqsk;	/* to talk to parasite daemons */
 		} net;
+		struct {
+			UsernsEntry *e;
+		} user;
 	};
 };
 extern struct ns_id *ns_ids;
diff --git a/criu/namespaces.c b/criu/namespaces.c
index 216fc079d..e2b0c6e7e 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -753,16 +753,14 @@ static int set_ns_hookups(struct ns_id *ns)
 	return ret;
 }
 
-static UsernsEntry userns_entry = USERNS_ENTRY__INIT;
+/* Mapping NS_ROOT to NS_CRIU */
+static UsernsEntry *userns_entry;
 #define INVALID_ID (~0U)
 
 static unsigned int userns_id(unsigned int id, UidGidExtent **map, int n)
 {
 	int i;
 
-	if (!(root_ns_mask & CLONE_NEWUSER))
-		return id;
-
 	for (i = 0; i < n; i++) {
 		if (map[i]->lower_first <= id &&
 		    map[i]->lower_first + map[i]->count > id)
@@ -790,25 +788,33 @@ static unsigned int host_id(unsigned int id, UidGidExtent **map, int n)
 
 static uid_t host_uid(uid_t uid)
 {
-	UsernsEntry *e = &userns_entry;
+	UsernsEntry *e = userns_entry;
 	return host_id(uid, e->uid_map, e->n_uid_map);
 }
 
 static gid_t host_gid(gid_t gid)
 {
-	UsernsEntry *e = &userns_entry;
+	UsernsEntry *e = userns_entry;
 	return host_id(gid, e->gid_map, e->n_gid_map);
 }
 
 uid_t userns_uid(uid_t uid)
 {
-	UsernsEntry *e = &userns_entry;
+	UsernsEntry *e = userns_entry;
+
+	if (!(root_ns_mask & CLONE_NEWUSER) || !e)
+		return uid;
+
 	return userns_id(uid, e->uid_map, e->n_uid_map);
 }
 
 gid_t userns_gid(gid_t gid)
 {
-	UsernsEntry *e = &userns_entry;
+	UsernsEntry *e = userns_entry;
+
+	if (!(root_ns_mask & CLONE_NEWUSER) || !e)
+		return gid;
+
 	return userns_id(gid, e->gid_map, e->n_gid_map);
 }
 
@@ -880,6 +886,15 @@ static int dump_user_ns(struct ns_id *ns);
 
 int collect_user_ns(struct ns_id *ns, void *oarg)
 {
+	UsernsEntry *e;
+
+	e = xmalloc(sizeof(*e));
+	if (!e)
+		return -1;
+	userns_entry__init(e);
+	ns->user.e = e;
+	if (ns->type == NS_ROOT)
+		userns_entry = e;
 	/*
 	 * User namespace is dumped before files to get uid and gid
 	 * mappings, which are used for convirting local id-s to
@@ -1023,7 +1038,7 @@ static int dump_user_ns(struct ns_id *ns)
 {
 	int ret, exit_code = -1;
 	pid_t pid = ns->ns_pid;
-	UsernsEntry *e = &userns_entry;
+	UsernsEntry *e = ns->user.e;
 	struct cr_img *img;
 
 	ret = parse_id_map(pid, "uid_map", &e->uid_map);
@@ -1060,16 +1075,29 @@ static int dump_user_ns(struct ns_id *ns)
 	return exit_code;
 }
 
-void free_userns_maps()
+static int do_free_userns_map(struct ns_id *ns, void *arg)
 {
-	if (userns_entry.n_uid_map > 0) {
-		xfree(userns_entry.uid_map[0]);
-		xfree(userns_entry.uid_map);
+	UsernsEntry *e = ns->user.e;
+
+	if (!e)
+		return 0;
+	if (e->n_uid_map > 0) {
+		xfree(e->uid_map[0]);
+		xfree(e->uid_map);
 	}
-	if (userns_entry.n_gid_map > 0) {
-		xfree(userns_entry.gid_map[0]);
-		xfree(userns_entry.gid_map);
+	if (e->n_gid_map > 0) {
+		xfree(e->gid_map[0]);
+		xfree(e->gid_map);
 	}
+	if (e == userns_entry)
+		userns_entry = NULL;
+	ns->user.e = NULL;
+
+	return 0;
+}
+void free_userns_maps()
+{
+	walk_namespaces(&user_ns_desc, do_free_userns_map, NULL);
 }
 
 static int do_dump_namespaces(struct ns_id *ns)



More information about the CRIU mailing list