ac3a84
From 7f0f2caa082e7490c160b2c992a094116474a95f Mon Sep 17 00:00:00 2001
ac3a84
From: Lennart Poettering <lennart@poettering.net>
ac3a84
Date: Fri, 4 Nov 2022 18:26:42 +0100
ac3a84
Subject: [PATCH] dissect: fix fsck
ac3a84
ac3a84
Since f7725647bb41c3398a867f139efe526efe8aa1b3 when dissecting a disk
ac3a84
image we operate with fds to the device nodes in question wherever we
ac3a84
can. This includes when we fork off fsck, where we pass a /proc/self/fd/
ac3a84
path as argument. This only works if we keep that fd open however and
ac3a84
disable O_CLOEXEC on the fd. Hence do so, and fix fsck this way.
ac3a84
ac3a84
(Without this, all fsck will fail, since the fd path is invalid)
ac3a84
ac3a84
(cherry picked from commit f8ab781223bcb0330ee4499b879a62e84fee313e)
ac3a84
ac3a84
Related: #2138081
ac3a84
---
ac3a84
 src/shared/dissect-image.c | 16 ++++++++++------
ac3a84
 1 file changed, 10 insertions(+), 6 deletions(-)
ac3a84
ac3a84
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
ac3a84
index 6a991c877a..7676636723 100644
ac3a84
--- a/src/shared/dissect-image.c
ac3a84
+++ b/src/shared/dissect-image.c
ac3a84
@@ -1309,11 +1309,11 @@ static int is_loop_device(const char *path) {
ac3a84
         return true;
ac3a84
 }
ac3a84
 
ac3a84
-static int run_fsck(const char *node, const char *fstype) {
ac3a84
+static int run_fsck(int node_fd, const char *fstype) {
ac3a84
         int r, exit_status;
ac3a84
         pid_t pid;
ac3a84
 
ac3a84
-        assert(node);
ac3a84
+        assert(node_fd >= 0);
ac3a84
         assert(fstype);
ac3a84
 
ac3a84
         r = fsck_exists_for_fstype(fstype);
ac3a84
@@ -1322,16 +1322,20 @@ static int run_fsck(const char *node, const char *fstype) {
ac3a84
                 return 0;
ac3a84
         }
ac3a84
         if (r == 0) {
ac3a84
-                log_debug("Not checking partition %s, as fsck for %s does not exist.", node, fstype);
ac3a84
+                log_debug("Not checking partition %s, as fsck for %s does not exist.", FORMAT_PROC_FD_PATH(node_fd), fstype);
ac3a84
                 return 0;
ac3a84
         }
ac3a84
 
ac3a84
-        r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO, &pid;;
ac3a84
+        r = safe_fork_full(
ac3a84
+                        "(fsck)",
ac3a84
+                        &node_fd, 1, /* Leave the node fd open */
ac3a84
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOEXEC_OFF,
ac3a84
+                        &pid;;
ac3a84
         if (r < 0)
ac3a84
                 return log_debug_errno(r, "Failed to fork off fsck: %m");
ac3a84
         if (r == 0) {
ac3a84
                 /* Child */
ac3a84
-                execl("/sbin/fsck", "/sbin/fsck", "-aT", node, NULL);
ac3a84
+                execl("/sbin/fsck", "/sbin/fsck", "-aT", FORMAT_PROC_FD_PATH(node_fd), NULL);
ac3a84
                 log_open();
ac3a84
                 log_debug_errno(errno, "Failed to execl() fsck: %m");
ac3a84
                 _exit(FSCK_OPERATIONAL_ERROR);
ac3a84
@@ -1421,7 +1425,7 @@ static int mount_partition(
ac3a84
         rw = m->rw && !(flags & DISSECT_IMAGE_MOUNT_READ_ONLY);
ac3a84
 
ac3a84
         if (FLAGS_SET(flags, DISSECT_IMAGE_FSCK) && rw) {
ac3a84
-                r = run_fsck(node, fstype);
ac3a84
+                r = run_fsck(m->mount_node_fd, fstype);
ac3a84
                 if (r < 0)
ac3a84
                         return r;
ac3a84
         }