[CRIU] [PATCH 06/11] util: Add cr_set_root/cr_restore_root helpers

Cyrill Gorcunov gorcunov at openvz.org
Tue Aug 2 08:34:32 PDT 2016


From: Andrew Vagin <avagin at virtuozzo.com>

They are needed to handle symlinks with absolute paths.

Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
---
 criu/include/util.h |  2 ++
 criu/util.c         | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/criu/include/util.h b/criu/include/util.h
index 5b7cad1134c1..e297f68bd301 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -277,6 +277,8 @@ void print_data(unsigned long addr, unsigned char *data, size_t size);
 int setup_tcp_server(char *type);
 int run_tcp_server(bool daemon_mode, int *ask, int cfd, int sk);
 int setup_tcp_client(char *addr);
+int cr_set_root(int fd, int *old_root);
+int cr_restore_root(int fd);
 
 #define LAST_PID_PATH		"sys/kernel/ns_last_pid"
 #define PID_MAX_PATH		"sys/kernel/pid_max"
diff --git a/criu/util.c b/criu/util.c
index c44d900c66ed..4598f343d93f 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1184,3 +1184,68 @@ int setup_tcp_client(char *addr)
 
 	return sk;
 }
+
+/*
+ * When reading symlinks via /proc/$pid/root/
+ * we should make sure the path resolving is done
+ * via root as toplevel root, otherwive path
+ * may be screwed.
+ *
+ * IOW, for any path resolving via /proc/$pid/root
+ * use this helper, and call cr_restore_root once
+ * you're done.
+ */
+int cr_set_root(int fd, int *old_root)
+{
+	int errno_save = errno;
+	int cwd = -1, old = -1;
+
+	if (old_root) {
+		old = open("/", O_PATH);
+		if (old < 0) {
+			pr_perror("Unable to open /");
+			return -1;
+		}
+	}
+
+	cwd = open(".", O_PATH);
+	if (cwd < 0)
+		goto err;
+
+	/* implement fchroot() */
+	if (fchdir(fd)) {
+		pr_perror("Unable to chdir");
+		goto err;
+	}
+	if (chroot(".")) {
+		pr_perror("Unable to chroot");
+		goto err;
+	}
+	if (fchdir(cwd)) {
+		pr_perror("Unable to restore cwd\n");
+		goto err;
+	}
+
+	close(cwd);
+
+	if (old_root)
+		*old_root = old;
+
+	errno = errno_save;
+	return 0;
+err:
+	close_safe(&cwd);
+	close_safe(&old);
+	errno = errno_save;
+	return -1;
+}
+
+int cr_restore_root(int root)
+{
+	int ret;
+
+	ret = cr_set_root(root, NULL);
+	close(root);
+
+	return ret;
+}
-- 
2.7.4



More information about the CRIU mailing list