]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: fix fsck 25266/head
authorLennart Poettering <lennart@poettering.net>
Fri, 4 Nov 2022 17:26:42 +0000 (18:26 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 4 Nov 2022 17:53:36 +0000 (18:53 +0100)
Since f7725647bb41c3398a867f139efe526efe8aa1b3 when dissecting a disk
image we operate with fds to the device nodes in question wherever we
can. This includes when we fork off fsck, where we pass a /proc/self/fd/
path as argument. This only works if we keep that fd open however and
disable O_CLOEXEC on the fd. Hence do so, and fix fsck this way.

(Without this, all fsck will fail, since the fd path is invalid)

src/shared/dissect-image.c

index 2989d31d3c295ec32b7136914cb9434f492e9363..cfa7d7e0f392c3f73be65cfc621d7d711b4584c4 100644 (file)
@@ -1327,11 +1327,11 @@ static int is_loop_device(const char *path) {
         return true;
 }
 
-static int run_fsck(const char *node, const char *fstype) {
+static int run_fsck(int node_fd, const char *fstype) {
         int r, exit_status;
         pid_t pid;
 
-        assert(node);
+        assert(node_fd >= 0);
         assert(fstype);
 
         r = fsck_exists_for_fstype(fstype);
@@ -1340,16 +1340,20 @@ static int run_fsck(const char *node, const char *fstype) {
                 return 0;
         }
         if (r == 0) {
-                log_debug("Not checking partition %s, as fsck for %s does not exist.", node, fstype);
+                log_debug("Not checking partition %s, as fsck for %s does not exist.", FORMAT_PROC_FD_PATH(node_fd), fstype);
                 return 0;
         }
 
-        r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO, &pid);
+        r = safe_fork_full(
+                        "(fsck)",
+                        &node_fd, 1, /* Leave the node fd open */
+                        FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_CLOEXEC_OFF,
+                        &pid);
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork off fsck: %m");
         if (r == 0) {
                 /* Child */
-                execl("/sbin/fsck", "/sbin/fsck", "-aT", node, NULL);
+                execl("/sbin/fsck", "/sbin/fsck", "-aT", FORMAT_PROC_FD_PATH(node_fd), NULL);
                 log_open();
                 log_debug_errno(errno, "Failed to execl() fsck: %m");
                 _exit(FSCK_OPERATIONAL_ERROR);
@@ -1439,7 +1443,7 @@ static int mount_partition(
         rw = m->rw && !(flags & DISSECT_IMAGE_MOUNT_READ_ONLY);
 
         if (FLAGS_SET(flags, DISSECT_IMAGE_FSCK) && rw) {
-                r = run_fsck(node, fstype);
+                r = run_fsck(m->mount_node_fd, fstype);
                 if (r < 0)
                         return r;
         }