[CRIU] [PATCH v2 29/36] ns: Implement set_user_ns()
Kirill Tkhai
ktkhai at virtuozzo.com
Fri Feb 3 08:15:55 PST 2017
Add a field pstree_item::user_ns, which shows the task's current
user_ns, and introduce helpers to set it.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/include/namespaces.h | 2 ++
criu/include/pstree.h | 1 +
criu/namespaces.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+)
diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h
index bf8b90eba..67a96d6b3 100644
--- a/criu/include/namespaces.h
+++ b/criu/include/namespaces.h
@@ -169,6 +169,8 @@ extern struct ns_id *lookup_ns_by_id(unsigned int id, struct ns_desc *nd);
extern int collect_user_namespaces(bool for_dump);
extern int prepare_userns(pid_t real_pid, UsernsEntry *e);
extern int create_ns_hierarhy(void);
+extern int __set_user_ns(struct ns_id *ns);
+extern int set_user_ns(u32 id);
extern int stop_usernsd(void);
extern uid_t userns_uid(uid_t uid);
diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index eeef6f87e..cb6ed90e6 100644
--- a/criu/include/pstree.h
+++ b/criu/include/pstree.h
@@ -29,6 +29,7 @@ struct pstree_item {
futex_t task_st;
unsigned long task_st_le_bits;
};
+ struct ns_id *user_ns;
};
enum {
diff --git a/criu/namespaces.c b/criu/namespaces.c
index 5a47a4971..0bbd57e96 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -2302,5 +2302,50 @@ int create_ns_hierarhy(void)
return 0;
}
+int __set_user_ns(struct ns_id *ns)
+{
+ int fd;
+
+ if (!(root_ns_mask & CLONE_NEWUSER))
+ return 0;
+
+ if (current->user_ns && current->user_ns->id == ns->id)
+ return 0;
+
+ fd = open_fd_of_real_pid(ns->owner.pid, ns->owner.fd, O_RDONLY);
+ if (fd < 0) {
+ pr_perror("Can't open ns fd");
+ return -1;
+ }
+ if (setns(fd, CLONE_NEWUSER) < 0) {
+ pr_perror("Can't setns");
+ close(fd);
+ return -1;
+ }
+ current->user_ns = ns;
+ close(fd);
+
+ if (prepare_userns_creds() < 0) {
+ pr_err("Can't set creds\n");
+ return -1;
+ }
+ return 0;
+}
+
+int set_user_ns(u32 id)
+{
+ struct ns_id *ns;
+
+ if (current->user_ns && current->user_ns->id == id)
+ return 0;
+
+ ns = lookup_ns_by_id(id, &user_ns_desc);
+ if (!ns) {
+ pr_err("Can't find user_ns %u\n", id);
+ return -1;
+ }
+ return __set_user_ns(ns);
+}
+
struct ns_desc pid_ns_desc = NS_DESC_ENTRY(CLONE_NEWPID, "pid");
struct ns_desc user_ns_desc = NS_DESC_ENTRY(CLONE_NEWUSER, "user");
More information about the CRIU
mailing list