[CRIU] [PATCH 14/17] zdtm: prepare a file tree for userns
Andrey Vagin
avagin at openvz.org
Fri Oct 31 02:14:32 PDT 2014
Here are two issues:
1. All mounts in a new user namespace are locked, so
we need to create a new root mount. We need to bind-mount root to
itself.
2. /proc and /sys must be mounted before umounting /proc and /sys
which were inhereted. It's a security policy.
"""
Author: Eric W. Biederman <ebiederm at xmission.com>
Date: Sun Mar 24 14:28:27 2013 -0700
userns: Restrict when proc and sysfs can be mounted
Only allow unprivileged mounts of proc and sysfs if they are already
mounted when the user namespace is created.
"""
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
test/zdtm/lib/ns.c | 48 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/test/zdtm/lib/ns.c b/test/zdtm/lib/ns.c
index a7e3261..9901f5f 100644
--- a/test/zdtm/lib/ns.c
+++ b/test/zdtm/lib/ns.c
@@ -19,8 +19,9 @@
extern int pivot_root(const char *new_root, const char *put_old);
static int prepare_mntns()
{
- int dfd;
+ int dfd, ret;
char *root;
+ char path[PATH_MAX];
root = getenv("ZDTM_ROOT");
if (!root) {
@@ -28,7 +29,28 @@ static int prepare_mntns()
return -1;
}
- dfd = open(".", O_RDONLY);
+ /*
+ * In a new userns all mounts are locked to protect what is
+ * under them. So we need to create another mount for the
+ * new root.
+ */
+ if (mount("/", "/", NULL, MS_PRIVATE | MS_REC, NULL)) {
+ fprintf(stderr, "Can't bind-mount root: %m\n");
+ return -1;
+ }
+
+ if (mount(root, root, NULL, MS_BIND | MS_REC, NULL)) {
+ fprintf(stderr, "Can't bind-mount root: %m\n");
+ return -1;
+ }
+
+ /* Move current working directory to the new root */
+ ret = readlink("/proc/self/cwd", path, sizeof(path) - 1);
+ if (ret < 0)
+ return -1;
+ path[ret] = 0;
+
+ dfd = open(path, O_RDONLY | O_DIRECTORY);
if (dfd == -1) {
fprintf(stderr, "open(.) failed: %m\n");
return -1;
@@ -43,27 +65,31 @@ static int prepare_mntns()
return -1;
}
- if (mount("none", "/", "none", MS_REC|MS_PRIVATE, NULL)) {
- fprintf(stderr, "Can't remount root with MS_PRIVATE: %m\n");
- return -1;
- }
-
if (pivot_root(".", "./old")) {
fprintf(stderr, "pivot_root(., ./old) failed: %m\n");
return -1;
}
- if (umount2("./old", MNT_DETACH)) {
- fprintf(stderr, "umount(./old) failed: %m\n");
- return -1;
- }
+
if (mkdir("proc", 0777) && errno != EEXIST) {
fprintf(stderr, "mkdir(proc) failed: %m\n");
return -1;
}
+
+ /*
+ * proc and sysfs can be mounted in an unprivileged namespace,
+ * if they are already mounted when the user namespace is created.
+ * So ./old must be umounted after mounting /proc and /sys.
+ */
if (mount("proc", "/proc", "proc", MS_MGC_VAL, NULL)) {
fprintf(stderr, "mount(/proc) failed: %m\n");
return -1;
}
+
+ if (umount2("./old", MNT_DETACH)) {
+ fprintf(stderr, "umount(./old) failed: %m\n");
+ return -1;
+ }
+
if (mkdir("/dev", 0755) && errno != EEXIST) {
fprintf(stderr, "mkdir(/dev) failed: %m\n");
return -1;
--
1.9.3
More information about the CRIU
mailing list