From: Benjamin Bouvier Date: Tue, 1 Oct 2019 09:12:10 +0000 (+0300) Subject: systemd-fsck: fix systemd-fsck/fsck pipe bad closure X-Git-Tag: v244-rc1~184 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4fc74554773969ab208427c8489bd21af4195db;p=thirdparty%2Fsystemd.git systemd-fsck: fix systemd-fsck/fsck pipe bad closure 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. --- diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 935dce9d218..55e6544d318 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -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)