summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/manager.c2
-rw-r--r--src/shared/utmp-wtmp.c14
-rw-r--r--src/systemctl/fuzz-systemctl-parse-argv.c58
-rw-r--r--src/systemctl/meson.build6
-rw-r--r--src/systemctl/systemctl-compat-telinit.c10
-rw-r--r--src/systemctl/systemctl-compat-telinit.h1
-rw-r--r--src/systemctl/systemctl.c23
-rw-r--r--src/systemctl/systemctl.h3
-rw-r--r--src/xdg-autostart-generator/fuzz-xdg-desktop.c2
9 files changed, 96 insertions, 23 deletions
diff --git a/src/core/manager.c b/src/core/manager.c
index 1881cde036..7458b0181b 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -510,7 +510,7 @@ static int manager_setup_signals(Manager *m) {
SIGCHLD, /* Child died */
SIGTERM, /* Reexecute daemon */
SIGHUP, /* Reload configuration */
- SIGUSR1, /* systemd/upstart: reconnect to D-Bus */
+ SIGUSR1, /* systemd: reconnect to D-Bus */
SIGUSR2, /* systemd: dump status */
SIGINT, /* Kernel sends us this on control-alt-del */
SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
index b36bc20512..3eeee24693 100644
--- a/src/shared/utmp-wtmp.c
+++ b/src/shared/utmp-wtmp.c
@@ -38,18 +38,10 @@ int utmp_get_runlevel(int *runlevel, int *previous) {
* very new and not apply to the current script being executed. */
e = getenv("RUNLEVEL");
- if (e && e[0] > 0) {
+ if (!isempty(e)) {
*runlevel = e[0];
-
- if (previous) {
- /* $PREVLEVEL seems to be an Upstart thing */
-
- e = getenv("PREVLEVEL");
- if (e && e[0] > 0)
- *previous = e[0];
- else
- *previous = 0;
- }
+ if (previous)
+ *previous = 0;
return 0;
}
diff --git a/src/systemctl/fuzz-systemctl-parse-argv.c b/src/systemctl/fuzz-systemctl-parse-argv.c
new file mode 100644
index 0000000000..f884917e17
--- /dev/null
+++ b/src/systemctl/fuzz-systemctl-parse-argv.c
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "env-util.h"
+#include "fd-util.h"
+#include "fuzz.h"
+#include "stdio-util.h"
+#include "strv.h"
+#include "systemctl.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ _cleanup_strv_free_ char **argv = NULL;
+ _cleanup_close_ int orig_stdout_fd = -1;
+ int r;
+
+ /* We don't want to fill the logs with messages about parse errors.
+ * Disable most logging if not running standalone */
+ if (!getenv("SYSTEMD_LOG_LEVEL"))
+ log_set_max_level(LOG_CRIT);
+
+ arg_pager_flags = PAGER_DISABLE; /* We shouldn't execute the pager */
+
+ argv = strv_parse_nulstr((const char *)data, size);
+ if (!argv)
+ return log_oom();
+
+ if (!argv[0])
+ return 0; /* argv[0] should always be present, but may be zero-length. */
+
+ if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) {
+ orig_stdout_fd = fcntl(fileno(stdout), F_DUPFD_CLOEXEC, 3);
+ if (orig_stdout_fd < 0)
+ 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 */
+ }
+
+ optind = 0; /* this tells the getopt machinery to reinitialize */
+
+ r = systemctl_dispatch_parse_argv(strv_length(argv), argv);
+ if (r < 0)
+ log_error_errno(r, "Failed to parse args: %m");
+ else
+ log_info(r == 0 ? "Done!" : "Action!");
+
+ if (orig_stdout_fd >= 0) {
+ char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+
+ xsprintf(path, "/proc/self/fd/%d", orig_stdout_fd);
+ assert_se(freopen(path, "w", stdout));
+ }
+
+ return 0;
+}
diff --git a/src/systemctl/meson.build b/src/systemctl/meson.build
index a6e254a14f..38bf33d49a 100644
--- a/src/systemctl/meson.build
+++ b/src/systemctl/meson.build
@@ -81,3 +81,9 @@ else
libshared_static,
libbasic_gcrypt]
endif
+
+fuzzers += [
+ [['src/systemctl/fuzz-systemctl-parse-argv.c',
+ systemctl_sources],
+ systemctl_link_with,
+ [], [], ['-DFUZZ_SYSTEMCTL_PARSE_ARGV']]]
diff --git a/src/systemctl/systemctl-compat-telinit.c b/src/systemctl/systemctl-compat-telinit.c
index f67361ea90..f0e9ca8d79 100644
--- a/src/systemctl/systemctl-compat-telinit.c
+++ b/src/systemctl/systemctl-compat-telinit.c
@@ -1,9 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
+#include <unistd.h>
#include "alloc-util.h"
#include "pretty-print.h"
+#include "rlimit-util.h"
#include "systemctl-compat-telinit.h"
#include "systemctl-daemon-reload.h"
#include "systemctl-start-unit.h"
@@ -150,3 +152,11 @@ int reload_with_fallback(void) {
return 0;
}
+
+int exec_telinit(char *argv[]) {
+ (void) rlimit_nofile_safe();
+ execv(TELINIT, argv);
+
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Couldn't find an alternative telinit implementation to spawn.");
+}
diff --git a/src/systemctl/systemctl-compat-telinit.h b/src/systemctl/systemctl-compat-telinit.h
index 1a2bcd4405..783c3878a0 100644
--- a/src/systemctl/systemctl-compat-telinit.h
+++ b/src/systemctl/systemctl-compat-telinit.h
@@ -4,3 +4,4 @@
int telinit_parse_argv(int argc, char *argv[]);
int start_with_fallback(void);
int reload_with_fallback(void);
+int exec_telinit(char *argv[]);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index e8e3d2438a..16d0555c7c 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -425,7 +425,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "after", no_argument, NULL, ARG_AFTER },
{ "before", no_argument, NULL, ARG_BEFORE },
{ "show-types", no_argument, NULL, ARG_SHOW_TYPES },
- { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
+ { "failed", no_argument, NULL, ARG_FAILED },
{ "full", no_argument, NULL, 'l' },
{ "job-mode", required_argument, NULL, ARG_JOB_MODE },
{ "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
@@ -926,7 +926,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return 1;
}
-static int parse_argv(int argc, char *argv[]) {
+int systemctl_dispatch_parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
@@ -970,14 +970,11 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = _ACTION_INVALID;
return telinit_parse_argv(argc, argv);
} else {
- /* Hmm, so some other init system is running, we need to forward this request to
- * it. For now we simply guess that it is Upstart. */
+ /* Hmm, so some other init system is running, we need to forward this request
+ * to it. */
- (void) rlimit_nofile_safe();
- execv(TELINIT, argv);
-
- return log_error_errno(SYNTHETIC_ERRNO(EIO),
- "Couldn't find an alternative telinit implementation to spawn.");
+ arg_action = ACTION_TELINIT;
+ return 1;
}
} else if (strstr(program_invocation_short_name, "runlevel")) {
@@ -990,6 +987,7 @@ static int parse_argv(int argc, char *argv[]) {
return systemctl_parse_argv(argc, argv);
}
+#ifndef FUZZ_SYSTEMCTL_PARSE_ARGV
static int systemctl_main(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_units },
@@ -1093,7 +1091,7 @@ static int run(int argc, char *argv[]) {
sigbus_install();
- r = parse_argv(argc, argv);
+ r = systemctl_dispatch_parse_argv(argc, argv);
if (r <= 0)
goto finish;
@@ -1143,6 +1141,10 @@ static int run(int argc, char *argv[]) {
r = runlevel_main();
break;
+ case ACTION_TELINIT:
+ r = exec_telinit(argv);
+ break;
+
case ACTION_EXIT:
case ACTION_SUSPEND:
case ACTION_HIBERNATE:
@@ -1166,3 +1168,4 @@ finish:
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+#endif
diff --git a/src/systemctl/systemctl.h b/src/systemctl/systemctl.h
index 34650ebb44..722853db2a 100644
--- a/src/systemctl/systemctl.h
+++ b/src/systemctl/systemctl.h
@@ -29,6 +29,7 @@ enum action {
ACTION_RELOAD,
ACTION_REEXEC,
ACTION_RUNLEVEL,
+ ACTION_TELINIT,
ACTION_CANCEL_SHUTDOWN,
_ACTION_MAX,
_ACTION_INVALID = -1
@@ -92,3 +93,5 @@ extern char **arg_clean_what;
extern TimestampStyle arg_timestamp_style;
extern bool arg_read_only;
extern bool arg_mkdir;
+
+int systemctl_dispatch_parse_argv(int argc, char *argv[]);
diff --git a/src/xdg-autostart-generator/fuzz-xdg-desktop.c b/src/xdg-autostart-generator/fuzz-xdg-desktop.c
index 23077e48dc..52ba7ff0a4 100644
--- a/src/xdg-autostart-generator/fuzz-xdg-desktop.c
+++ b/src/xdg-autostart-generator/fuzz-xdg-desktop.c
@@ -3,12 +3,12 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "fs-util.h"
+#include "fuzz.h"
#include "rm-rf.h"
#include "string-util.h"
#include "strv.h"
#include "tests.h"
#include "tmpfile-util.h"
-#include "fuzz.h"
#include "xdg-autostart-service.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {