[CRIU] [PATCH] remap: fix dead pid remap of /proc/<pid>
Tycho Andersen
tycho.andersen at canonical.com
Wed Jan 6 07:57:30 PST 2016
It turns out we can't just test for /proc/<pid>, because the kernel appends
(deleted), since the directory is actually deleted (vs. something like
/proc/1/mountinfo, where the file still exists in the unlinked directory,
so there is no (deleted)). See comment for details.
Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
files-reg.c | 34 +++++++++++++++++++++++++---------
test/zdtm/live/static/remap_dead_pid.c | 22 ++++++++++++++++++++--
2 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/files-reg.c b/files-reg.c
index 0f89be5..43872f0 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -887,16 +887,32 @@ static int check_path_remap(struct fd_link *link, const struct fd_parms *parms,
return -1;
pid = strtol(start + 1, &end, 10);
- /* if we didn't find another /, this path something
- * like ./proc/kmsg, which we shouldn't mess with. */
- if (*end == '/') {
- *end = 0;
- ret = access(rpath, F_OK);
- *end = '/';
-
- if (ret) {
+ /* If strtol didn't convert anything, then we are looking at
+ * something like /proc/kmsg, which we shouldn't mess with.
+ * Anything under /proc/<pid> (including that directory itself)
+ * can be c/r'd with a dead pid remap, so let's allow all such
+ * cases.
+ */
+ if (pid != 0) {
+ bool is_dead = strip_deleted(link);
+
+ /* /proc/<pid> will be "/proc/1 (deleted)" when it is
+ * dead, but a path like /proc/1/mountinfo won't have
+ * the suffix, since it isn't actually deleted (still
+ * exists, but the parent dir is deleted). So, if we
+ * have a path like /proc/1/mountinfo, test if /proc/1
+ * exists instead, since this is what CRIU will need to
+ * open on restore.
+ */
+ if (!is_dead) {
+ *end = 0;
+ ret = access(rpath, F_OK);
+ *end = '/';
+ }
+
+ if (is_dead) {
pr_info("Dumping dead process remap of %d\n", pid);
- return dump_dead_process_remap(pid, rpath + 1, plen - 1, ost, lfd, id, nsid);
+ return dump_dead_process_remap(pid, rpath + 1, link->len - 1, ost, lfd, id, nsid);
}
}
diff --git a/test/zdtm/live/static/remap_dead_pid.c b/test/zdtm/live/static/remap_dead_pid.c
index c16832d..a9d5d1a 100644
--- a/test/zdtm/live/static/remap_dead_pid.c
+++ b/test/zdtm/live/static/remap_dead_pid.c
@@ -36,13 +36,23 @@ int main(int argc, char **argv)
while(1)
sleep(10);
} else {
- int fd, ret;
+ int fd, fd2, ret;
char path[PATH_MAX];
pid_t result;
sprintf(path, "/proc/%d/mountinfo", pid);
-
fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ fail("failed to open fd");
+ return -1;
+ }
+
+ sprintf(path, "/proc/%d", pid);
+ fd2 = open(path, O_RDONLY);
+ if (fd2 < 0) {
+ fail("failed to open fd2");
+ return -1;
+ }
/* no matter what, we should kill the child */
kill(pid, SIGKILL);
@@ -67,6 +77,14 @@ int main(int argc, char **argv)
fail("bad fd after restore");
return -1;
}
+
+ ret = fcntl(fd2, F_GETFD);
+ close(fd2);
+
+ if (ret) {
+ fail("bad fd2 after restore");
+ return -1;
+ }
}
pass();
--
2.5.0
More information about the CRIU
mailing list