]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemd-fsck: fix systemd-fsck/fsck pipe bad closure
authorBenjamin Bouvier <benjamin.bouvier@nokia.com>
Tue, 1 Oct 2019 09:12:10 +0000 (12:12 +0300)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 18 Oct 2019 14:07:00 +0000 (16:07 +0200)
Currently, when console is disabled but progress is tracked, pipe opened
for communication between systemd-fsck and fsck may be closed
inadvertently (when opening of /dev/console return in error). That lead
to finish fsck prematurely (because it receives a SIGPIPE) and so fsck
may not check correctly filesystems and do not have time to fix memory
corruptions.

This commit changes the opening of /dev/console to be done previously to
pipe creation and so fix the bug described just above.

src/fsck/fsck.c

index 935dce9d218b86c8427bfa2aadf4d9d68175f987..55e6544d318b4ab042ed2523e73287bf5a420d9a 100644 (file)
@@ -156,8 +156,8 @@ static double percent(int pass, unsigned long cur, unsigned long max) {
                 (double) cur / (double) max;
 }
 
-static int process_progress(int fd) {
-        _cleanup_fclose_ FILE *console = NULL, *f = NULL;
+static int process_progress(int fd, FILE* console) {
+        _cleanup_fclose_ FILE *f = NULL;
         usec_t last = 0;
         bool locked = false;
         int clear = 0, r;
@@ -172,10 +172,6 @@ static int process_progress(int fd) {
                 return log_debug_errno(errno, "Failed to use pipe: %m");
         }
 
-        console = fopen("/dev/console", "we");
-        if (!console)
-                return log_debug_errno(errno, "Failed to open /dev/console, can't print progress output: %m");
-
         for (;;) {
                 int pass, m;
                 unsigned long cur, max;
@@ -254,6 +250,7 @@ static int run(int argc, char *argv[]) {
         _cleanup_close_pair_ int progress_pipe[2] = { -1, -1 };
         _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
         _cleanup_free_ char *dpath = NULL;
+        _cleanup_fclose_ FILE *console = NULL;
         const char *device, *type;
         bool root_directory;
         struct stat st;
@@ -342,7 +339,9 @@ static int run(int argc, char *argv[]) {
                 }
         }
 
-        if (arg_show_progress &&
+        console = fopen("/dev/console", "we");
+        if (console &&
+            arg_show_progress &&
             pipe(progress_pipe) < 0)
                 return log_error_errno(errno, "pipe(): %m");
 
@@ -401,8 +400,10 @@ static int run(int argc, char *argv[]) {
                 _exit(FSCK_OPERATIONAL_ERROR);
         }
 
-        progress_pipe[1] = safe_close(progress_pipe[1]);
-        (void) process_progress(TAKE_FD(progress_pipe[0]));
+        if (console) {
+                progress_pipe[1] = safe_close(progress_pipe[1]);
+                (void) process_progress(TAKE_FD(progress_pipe[0]), console);
+        }
 
         exit_status = wait_for_terminate_and_check("fsck", pid, WAIT_LOG_ABNORMAL);
         if (exit_status < 0)