[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