[CRIU] [PATCH 17/17] userns: check that all namespaces were created from a target userns
Andrey Vagin
avagin at openvz.org
Fri Oct 31 02:14:35 PDT 2014
We enter into the target userns and try to enter in other namespaces.
The "enter" operation requires CAP_SYS_ADMIN in a user namespace,
where a taget namespace was created.
Now if one or more namespaces were created in another userns,
criu stops dumping and return an error. I want to find someone, who uses
this configuration. In this case restore will be more complicated.
Current version covers containers needs.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
namespaces.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/namespaces.c b/namespaces.c
index cc69aab..96e616e 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -572,12 +572,64 @@ err:
return -1;
}
+static int check_user_ns(int pid)
+{
+ int status;
+ pid_t chld;
+
+ chld = fork();
+ if (chld == -1) {
+ pr_perror("Unable to fork a process\n");
+ return -1;
+ }
+
+ if (chld == 0) {
+ /*
+ * Check that we are able to enter into other namespaces
+ * from the target userns namespace. This signs that these
+ * namespaces were created from the target userns.
+ */
+
+ if (switch_ns(pid, &user_ns_desc, NULL))
+ exit(-1);
+
+ if ((root_ns_mask & CLONE_NEWNET) &&
+ switch_ns(pid, &net_ns_desc, NULL))
+ exit(-1);
+ if ((root_ns_mask & CLONE_NEWUTS) &&
+ switch_ns(pid, &uts_ns_desc, NULL))
+ exit(-1);
+ if ((root_ns_mask & CLONE_NEWIPC) &&
+ switch_ns(pid, &ipc_ns_desc, NULL))
+ exit(-1);
+ if ((root_ns_mask & CLONE_NEWNS) &&
+ switch_ns(pid, &mnt_ns_desc, NULL))
+ exit(-1);
+ exit(0);
+ }
+
+ if (waitpid(chld, &status, 0) != chld) {
+ pr_perror("Unable to wait the %d process", pid);
+ return -1;
+ }
+
+ if (status) {
+ pr_err("One or more namespaces doesn't belong to the target user namespace\n");
+ return -1;
+ }
+
+ return 0;
+}
+
int dump_user_ns(pid_t pid, int ns_id)
{
int ret, exit_code = -1;
UsernsEntry *e = &userns_entry;
struct cr_img *img;
+ if (check_user_ns(pid))
+ return -1;
+
ret = parse_id_map(pid, "uid_map", &e->uid_map);
if (ret < 0)
goto err;
--
1.9.3
More information about the CRIU
mailing list