mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 14:25:49 +00:00
ns: Implement set_user_ns()
Add a field pstree_item::user_ns, which shows the task's current user_ns, and introduce helpers to set it. v3: Rebase on fdstore Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
committed by
Andrei Vagin
parent
f9582b0bd3
commit
87ad5ec22c
@@ -164,6 +164,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 collect_user_namespaces(bool for_dump);
|
||||||
extern int prepare_userns(pid_t real_pid, UsernsEntry *e);
|
extern int prepare_userns(pid_t real_pid, UsernsEntry *e);
|
||||||
|
extern int __set_user_ns(struct ns_id *ns);
|
||||||
|
extern int set_user_ns(u32 id);
|
||||||
extern int stop_usernsd(void);
|
extern int stop_usernsd(void);
|
||||||
|
|
||||||
extern uid_t userns_uid(uid_t uid);
|
extern uid_t userns_uid(uid_t uid);
|
||||||
|
@@ -29,6 +29,7 @@ struct pstree_item {
|
|||||||
futex_t task_st;
|
futex_t task_st;
|
||||||
unsigned long task_st_le_bits;
|
unsigned long task_st_le_bits;
|
||||||
};
|
};
|
||||||
|
struct ns_id *user_ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline pid_t vpid(const struct pstree_item *i)
|
static inline pid_t vpid(const struct pstree_item *i)
|
||||||
|
@@ -2277,5 +2277,50 @@ err_unds:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = fdstore_get(ns->user.nsfd_id);
|
||||||
|
if (fd < 0) {
|
||||||
|
pr_err("Can't get ns fd\n");
|
||||||
|
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 pid_ns_desc = NS_DESC_ENTRY(CLONE_NEWPID, "pid");
|
||||||
struct ns_desc user_ns_desc = NS_DESC_ENTRY(CLONE_NEWUSER, "user");
|
struct ns_desc user_ns_desc = NS_DESC_ENTRY(CLONE_NEWUSER, "user");
|
||||||
|
Reference in New Issue
Block a user