From 4a30028c85e137996fd87dff236dd037d14acad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 14 May 2026 00:21:25 +0200 Subject: [PATCH] fuzz-systemctl-parse-argv: update suppression of logging and resetting of state 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 | 8 +++----- src/systemctl/systemctl-compat-halt.c | 8 ++++++-- src/systemctl/systemctl-compat-halt.h | 3 +-- src/systemctl/systemctl-compat-shutdown.c | 8 ++++++-- src/systemctl/systemctl-compat-shutdown.h | 2 +- src/systemctl/systemctl-main.c | 2 +- src/systemctl/systemctl.c | 21 +++++++++++++-------- src/systemctl/systemctl.h | 2 +- 8 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/systemctl/fuzz-systemctl-parse-argv.c b/src/systemctl/fuzz-systemctl-parse-argv.c index c57faa6771..9d487f7c6e 100644 --- a/src/systemctl/fuzz-systemctl-parse-argv.c +++ b/src/systemctl/fuzz-systemctl-parse-argv.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include #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 diff --git a/src/systemctl/systemctl-compat-halt.c b/src/systemctl/systemctl-compat-halt.c index 3f19a263ff..217487b643 100644 --- a/src/systemctl/systemctl-compat-halt.c +++ b/src/systemctl/systemctl-compat-halt.c @@ -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) { diff --git a/src/systemctl/systemctl-compat-halt.h b/src/systemctl/systemctl-compat-halt.h index 85b9dda0e4..3658e52e1a 100644 --- a/src/systemctl/systemctl-compat-halt.h +++ b/src/systemctl/systemctl-compat-halt.h @@ -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); diff --git a/src/systemctl/systemctl-compat-shutdown.c b/src/systemctl/systemctl-compat-shutdown.c index f4dbd80473..d93fa91ca0 100644 --- a/src/systemctl/systemctl-compat-shutdown.c +++ b/src/systemctl/systemctl-compat-shutdown.c @@ -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) { diff --git a/src/systemctl/systemctl-compat-shutdown.h b/src/systemctl/systemctl-compat-shutdown.h index 7acf9414c9..9181a31f86 100644 --- a/src/systemctl/systemctl-compat-shutdown.h +++ b/src/systemctl/systemctl-compat-shutdown.h @@ -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); diff --git a/src/systemctl/systemctl-main.c b/src/systemctl/systemctl-main.c index 395874d563..8e2b1c170d 100644 --- a/src/systemctl/systemctl-main.c +++ b/src/systemctl/systemctl-main.c @@ -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; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 817ee71980..d5473cdc0a 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -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); } } diff --git a/src/systemctl/systemctl.h b/src/systemctl/systemctl.h index 58ad1e5876..e157ab12f0 100644 --- a/src/systemctl/systemctl.h +++ b/src/systemctl/systemctl.h @@ -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);