]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fsck: copy out device argument from argv[] before forking
authorLennart Poettering <lennart@poettering.net>
Thu, 28 Mar 2019 18:26:21 +0000 (19:26 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 29 Mar 2019 07:18:25 +0000 (08:18 +0100)
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

index 524327c4da04c87e6d38561e5731baef57756c37..8101f9ce95853284cf4260236dd22a06e1766d82 100644 (file)
@@ -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);