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:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user