diff options
author | Benjamin Bouvier <benjamin.bouvier@nokia.com> | 2019-10-01 11:12:10 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-10-18 16:07:00 +0200 |
commit | e4fc74554773969ab208427c8489bd21af4195db (patch) | |
tree | b57e7e4943a88566aa54595cfde7219053a69f59 /src/fsck | |
parent | coredump: Include module offsets in stack traces (diff) | |
download | systemd-e4fc74554773969ab208427c8489bd21af4195db.tar.xz systemd-e4fc74554773969ab208427c8489bd21af4195db.zip |
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.
Diffstat (limited to 'src/fsck')
-rw-r--r-- | src/fsck/fsck.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 935dce9d21..55e6544d31 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) |