[CRIU] [PATCH] Resolve file descriptor clashes with inherit fds

Saied Kazemi saied at google.com
Tue Nov 25 14:54:05 PST 2014


Since with --inherit-fd option criu's caller can set any fd to be
inheritied, there is a chance of fd clash during restore.  Resolve such
cases by moving the inherit fd to a different descriptor.

Signed-off-by: Saied Kazemi <saied at google.com>
---
 files-reg.c     |  1 -
 files.c         | 25 ++++++++++++++++++++++---
 include/files.h |  3 ++-
 util.c          |  3 +++
 4 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/files-reg.c b/files-reg.c
index bfd1896..2d2328c 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -963,7 +963,6 @@ int open_path(struct file_desc *d,
 
 	mntns_root = mntns_get_root_by_mnt_id(rfi->rfe->mnt_id);
 
-pr_debug(">>> open_path(): rfi->path=(%s)\n", rfi->path);
 	tmp = inherit_fd_lookup_id(rfi->path, true);
 	if (tmp >= 0) {
 		pr_info("File %s will be restored from fd %d\n", rfi->path, tmp);
diff --git a/files.c b/files.c
index 7bace3a..a074be5 100644
--- a/files.c
+++ b/files.c
@@ -1346,16 +1346,35 @@ int inherit_fd_lookup_id(char *id, bool need_fd)
 /*
  * Look up the inherit fd list by a file descriptor.
  */
-bool inherit_fd_lookup_fd(int fd)
+struct inherit_fd *inherit_fd_lookup_fd(int fd)
 {
 	struct inherit_fd *inh;
 
 	list_for_each_entry(inh, &opts.inherit_fds, l) {
 		if (inh->inh_fd == fd) {
 			pr_info("File descriptor %d in inherit fd list\n", fd);
-			return true;
+			return inh;
 		}
 	}
 
-	return false;
+	return NULL;
+}
+
+/*
+ * If the specified fd clashes with an inherit fd,
+ * move the inherit fd.
+ */
+int inherit_fd_resolve_clash(int fd)
+{
+	struct inherit_fd *inh;
+
+	if ((inh = inherit_fd_lookup_fd(fd)) == NULL)
+		return 0;
+
+	if ((inh->inh_fd = dup(fd)) == -1 || close(fd) == -1) {
+		pr_perror("Can't resolve inherit fd clash on %d", fd);
+		return -1;
+	}
+	pr_debug("Resolved clash on inherit fd %d -> %d\n", fd, inh->inh_fd);
+	return 0;
 }
diff --git a/include/files.h b/include/files.h
index e4e304f..aa0e502 100644
--- a/include/files.h
+++ b/include/files.h
@@ -174,6 +174,7 @@ extern int inherit_fd_add(char *optarg);
 extern void inherit_fd_log(void);
 extern int inherit_fd_validate_fds(void);
 extern int inherit_fd_lookup_id(char *id, bool need_fd);
-extern bool inherit_fd_lookup_fd(int fd);
+extern struct inherit_fd *inherit_fd_lookup_fd(int fd);
+extern int inherit_fd_resolve_clash(int fd);
 
 #endif /* __CR_FILES_H__ */
diff --git a/util.c b/util.c
index 3b468f2..4d2ef17 100644
--- a/util.c
+++ b/util.c
@@ -118,6 +118,9 @@ int reopen_fd_as_safe(char *file, int line, int new_fd, int old_fd, bool allow_r
 	int tmp;
 
 	if (old_fd != new_fd) {
+		/* make sure we won't clash with an inherit fd */
+		if (inherit_fd_resolve_clash(new_fd) < 0)
+			return -1;
 
 		if (!allow_reuse_fd) {
 			if (fcntl(new_fd, F_GETFD) != -1 || errno != EBADF) {
-- 
2.2.0.rc0.207.ga3a616c



More information about the CRIU mailing list