mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
fuzz-systemctl-parse-argv: a new fuzzer
Does what the name suggests. Obviously inspired by sudoers, but note that our tools are not supposed to be installed suid, so there is no privilege boundary to cross here.
This commit is contained in:
parent
5bb920ce27
commit
5fd8782328
58
src/systemctl/fuzz-systemctl-parse-argv.c
Normal file
58
src/systemctl/fuzz-systemctl-parse-argv.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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']]]
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -987,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 },
|
||||
|
@ -1090,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;
|
||||
|
||||
|
@ -1167,3 +1168,4 @@ finish:
|
|||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
|
||||
#endif
|
||||
|
|
|
@ -93,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[]);
|
||||
|
|
BIN
test/fuzz/fuzz-systemctl-parse-argv/help.input
Normal file
BIN
test/fuzz/fuzz-systemctl-parse-argv/help.input
Normal file
Binary file not shown.
Loading…
Reference in a new issue