From bd169c2be0fbdaf6eb2ea7951e650d5e5983fbf6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 28 Mar 2019 19:26:21 +0100 Subject: [PATCH] fsck: copy out device argument from argv[] before forking We nowadays rename our child processes, hence argv[] will be clobbered, let's hence copy the device path to dynamic memory before forking. This is fall-out from 60ffa37a65a96c3af857a3dfc4a6fd47b20cc90e since we now a lot more often end up overriding the argv[] buffer than before, simple because we know what to override. These kind of bugs kinda suck. THere are only two options here: stop overriding argv[] for all cases (or just these cases) or explicitly copying out everything we need in child processes before forking. With this patch I opt for the latter, though I am not 100% convinced this is a great solution. Just a better solution than everything else, i.e. allowing argv[] to remain out of sync with what others see. Fixes: #12135 --- src/fsck/fsck.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 524327c4da..8101f9ce95 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -265,6 +265,7 @@ static int fsck_progress_socket(void) { 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; const char *device, *type; bool root_directory; struct stat st; @@ -290,7 +291,11 @@ static int run(int argc, char *argv[]) { return 0; if (argc > 1) { - device = argv[1]; + dpath = strdup(argv[1]); + if (!dpath) + return log_oom(); + + device = dpath; if (stat(device, &st) < 0) return log_error_errno(errno, "Failed to stat %s: %m", device);