]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fuzz-systemctl-parse-argv: update suppression of logging and resetting of state
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Wed, 13 May 2026 22:21:25 +0000 (00:21 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Thu, 14 May 2026 07:38:10 +0000 (09:38 +0200)
There's certainly more than one way to skin this particular cat,
so I'm keeping this as a separate commit.

src/systemctl/fuzz-systemctl-parse-argv.c
src/systemctl/systemctl-compat-halt.c
src/systemctl/systemctl-compat-halt.h
src/systemctl/systemctl-compat-shutdown.c
src/systemctl/systemctl-compat-shutdown.h
src/systemctl/systemctl-main.c
src/systemctl/systemctl.c
src/systemctl/systemctl.h

index c57faa6771e45d34efa5ee20592066e3ac15e81f..9d487f7c6ea64d715d229edabefc86807d1ab7af 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <getopt.h>
 #include <stdio.h>
 
 #include "bus-util.h"
@@ -88,17 +87,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
                         log_warning_errno(orig_stdout_fd, "Failed to duplicate fd 1: %m");
                 else
                         assert_se(freopen("/dev/null", "w", stdout));
-
-                opterr = 0; /* do not print errors */
         }
 
         /* We need to reset some global state manually here since libfuzzer feeds a single process with
          * multiple inputs, so we might carry over state from previous invocations that can trigger
          * certain asserts. */
-        optind = 0; /* this tells the getopt machinery to reinitialize */
         arg_transport = BUS_TRANSPORT_LOCAL;
 
-        r = systemctl_dispatch_parse_argv(strv_length(argv), argv, /* remaining_args= */ NULL);
+        r = systemctl_dispatch_parse_argv(strv_length(argv), argv,
+                                          /* log_level_shift= */ LOG_DEBUG - LOG_ERR,
+                                          /* remaining_args= */ NULL);
         if (r < 0)
                 log_error_errno(r, "Failed to parse args: %m");
         else
index 3f19a263ff00f7d5c0f14305907e2f1cd3fde5ef..217487b64350ce576628549bf83e67196d71f0e3 100644 (file)
@@ -50,13 +50,17 @@ static int halt_help(void) {
         return 0;
 }
 
-int halt_parse_argv(int argc, char *argv[]) {
+int halt_parse_argv(int argc, char *argv[], int log_level_shift) {
         int r;
 
         assert(argc >= 0);
         assert(argv);
 
-        OptionParser opts = { argc, argv, .namespace = "halt" };
+        OptionParser opts = {
+                argc, argv,
+                .namespace = "halt",
+                .log_level_shift = log_level_shift,
+        };
 
         FOREACH_OPTION_OR_RETURN(c, &opts)
                 switch (c) {
index 85b9dda0e4a0e6252c771e8e5914caf364c8a0d1..3658e52e1aa21d996d13ddf522506c5f0d0b432c 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-int halt_parse_argv(int argc, char *argv[]);
-
+int halt_parse_argv(int argc, char *argv[], int log_level_shift);
 int halt_main(void);
index f4dbd80473aada4998118c7f22cb013caa05b18f..d93fa91ca09ecc4c9e2a16dc999b7baa58f488ce 100644 (file)
@@ -116,13 +116,17 @@ static int parse_shutdown_time_spec(const char *t, usec_t *ret) {
         return 0;
 }
 
-int shutdown_parse_argv(int argc, char *argv[]) {
+int shutdown_parse_argv(int argc, char *argv[], int log_level_shift) {
         int r;
 
         assert(argc >= 0);
         assert(argv);
 
-        OptionParser opts = { argc, argv, .namespace = "shutdown" };
+        OptionParser opts = {
+                argc, argv,
+                .namespace = "shutdown",
+                .log_level_shift = log_level_shift,
+        };
 
         FOREACH_OPTION_OR_RETURN(c, &opts)
                 switch (c) {
index 7acf9414c9ab9f7d9b64b236c8cf0f3c8ee5b4f7..9181a31f862f9f8960f5c5b9640a9ebcf28fea1e 100644 (file)
@@ -1,4 +1,4 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-int shutdown_parse_argv(int argc, char *argv[]);
+int shutdown_parse_argv(int argc, char *argv[], int log_level_shift);
index 395874d5637c00a477a03c08ea0225e777809489..8e2b1c170d5f556254dc721c48a6b4e1e534e4da 100644 (file)
@@ -26,7 +26,7 @@ static int run(int argc, char *argv[]) {
         setlocale(LC_ALL, "");
         log_setup();
 
-        r = systemctl_dispatch_parse_argv(argc, argv, &args);
+        r = systemctl_dispatch_parse_argv(argc, argv, /* log_level_shift= */ 0, &args);
         if (r <= 0)
                 goto finish;
 
index 817ee719807aa85b6e09e3a08c8522ae3b2a51a6..d5473cdc0af4b7d14bcc933585ee1507f26118f2 100644 (file)
@@ -373,7 +373,7 @@ static int parse_what_argument(const char *value, char ***clean_what) {
         return 1;
 }
 
-static int systemctl_parse_argv(int argc, char *argv[], char ***remaining_args) {
+static int systemctl_parse_argv(int argc, char *argv[], int log_level_shift, char ***remaining_args) {
         int r;
 
         assert(argc >= 0);
@@ -382,7 +382,11 @@ static int systemctl_parse_argv(int argc, char *argv[], char ***remaining_args)
         /* We default to allowing interactive authorization only in systemctl (not in the legacy commands) */
         arg_ask_password = true;
 
-        OptionParser opts = { argc, argv, .namespace = "systemctl" };
+        OptionParser opts = {
+                argc, argv,
+                .namespace = "systemctl",
+                .log_level_shift = log_level_shift,
+        };
 
         FOREACH_OPTION_OR_RETURN(c, &opts)
                 switch (c) {
@@ -898,28 +902,29 @@ static int systemctl_parse_argv(int argc, char *argv[], char ***remaining_args)
         return 1;
 }
 
-int systemctl_dispatch_parse_argv(int argc, char *argv[], char ***remaining_args) {
+int systemctl_dispatch_parse_argv(int argc, char *argv[], int log_level_shift, char ***remaining_args) {
         assert(argc >= 0);
         assert(argv);
 
         if (invoked_as(argv, "halt")) {
                 arg_action = ACTION_HALT;
-                return halt_parse_argv(argc, argv);
+                return halt_parse_argv(argc, argv, log_level_shift);
 
         } else if (invoked_as(argv, "poweroff")) {
                 arg_action = ACTION_POWEROFF;
-                return halt_parse_argv(argc, argv);
+                return halt_parse_argv(argc, argv, log_level_shift);
 
         } else if (invoked_as(argv, "reboot")) {
                 arg_action = ACTION_REBOOT;
-                return halt_parse_argv(argc, argv);
+                return halt_parse_argv(argc, argv, log_level_shift);
 
         } else if (invoked_as(argv, "shutdown")) {
                 arg_action = ACTION_POWEROFF;
-                return shutdown_parse_argv(argc, argv);
+                return shutdown_parse_argv(argc, argv, log_level_shift);
+
         } else {
                 arg_action = ACTION_SYSTEMCTL;
-                return systemctl_parse_argv(argc, argv, remaining_args);
+                return systemctl_parse_argv(argc, argv, log_level_shift, remaining_args);
         }
 }
 
index 58ad1e5876117dbb7a4380c2fd1b53782e884ffd..e157ab12f067fd8795f321f269d9a472f8cae8e4 100644 (file)
@@ -102,5 +102,5 @@ static inline const char* arg_job_mode(void) {
         return _arg_job_mode ?: "replace";
 }
 
-int systemctl_dispatch_parse_argv(int argc, char *argv[], char ***remaining_args);
+int systemctl_dispatch_parse_argv(int argc, char *argv[], int log_level_shift, char ***remaining_args);
 int systemctl_main(char **args);