[CRIU] [PATCH 1/2] util: Add cr_set_root/cr_restore_root helpers
Cyrill Gorcunov
gorcunov at openvz.org
Tue Jun 7 11:07:36 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 openvz.org>
---
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 72fbd1d09d57..5e3c49305ba7 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"
diff --git a/criu/util.c b/criu/util.c
index f518847ca7f4..9b088f0a9e8f 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1178,3 +1178,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.5.5
More information about the CRIU
mailing list