dcavalca / rpms / systemd

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