diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-05-03 21:45:26 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-03 21:45:26 +0900 |
commit | a76dc1f3a042adf203a79c34846563f5528b17bb (patch) | |
tree | 3532a8322f6d26e5c03435161335531195ecf4fe /src | |
parent | 406004a6c3fa38c1752056adf2ef59523e5ff534 (diff) | |
parent | 740831076cfcf2f73f3063fbb040c1ea593dfe6c (diff) | |
download | systemd-a76dc1f3a042adf203a79c34846563f5528b17bb.tar.gz |
Merge pull request #27504 from mrc0mmand/fuzz-manager-serialize
test: add a simple fuzzer for manager serialization
Diffstat (limited to 'src')
-rw-r--r-- | src/core/fuzz-manager-serialize.c | 38 | ||||
-rw-r--r-- | src/core/meson.build | 7 | ||||
-rw-r--r-- | src/core/service.c | 5 | ||||
-rw-r--r-- | src/shared/bpf-program.c | 3 | ||||
-rw-r--r-- | src/shared/varlink.c | 4 |
5 files changed, 56 insertions, 1 deletions
diff --git a/src/core/fuzz-manager-serialize.c b/src/core/fuzz-manager-serialize.c new file mode 100644 index 0000000000..04560341da --- /dev/null +++ b/src/core/fuzz-manager-serialize.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <stdio.h> + +#include "alloc-util.h" +#include "fd-util.h" +#include "fuzz.h" +#include "manager-serialize.h" +#include "manager.h" +#include "service.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + _cleanup_(manager_freep) Manager *m = NULL; + _cleanup_fclose_ FILE *f = NULL, *null = NULL; + _cleanup_fdset_free_ FDSet *fdset = NULL; + + /* 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); + log_set_target(LOG_TARGET_NULL); + } + + assert_se(manager_new(RUNTIME_SCOPE_SYSTEM, MANAGER_TEST_RUN_BASIC, &m) >= 0); + /* Set log overrides as well to make it harder for a serialization file + * to switch log levels/targets during fuzzing */ + manager_override_log_level(m, log_get_max_level()); + manager_override_log_target(m, log_get_target()); + assert_se(null = fopen("/dev/null", "we")); + assert_se(fdset = fdset_new()); + assert_se(f = data_to_file(data, size)); + + (void) manager_deserialize(m, f, fdset); + (void) manager_serialize(m, null, fdset, true); + (void) manager_serialize(m, null, fdset, false); + + return 0; +} diff --git a/src/core/meson.build b/src/core/meson.build index 1a1b8b310d..152b5d4c5d 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -192,4 +192,11 @@ fuzzers += [ ], 'dependencies' : libmount, }, + { + 'sources' : files('fuzz-manager-serialize.c'), + 'link_with' : [ + libcore, + libshared + ], + }, ] diff --git a/src/core/service.c b/src/core/service.c index c035f4c24e..2ba7511ad2 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3219,6 +3219,11 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, } else if (streq(key, "accept-socket")) { Unit *socket; + if (u->type != UNIT_SOCKET) { + log_unit_debug(u, "Failed to deserialize accept-socket: unit is not a socket"); + return 0; + } + r = manager_load_unit(u->manager, value, NULL, NULL, &socket); if (r < 0) log_unit_debug_errno(u, r, "Failed to load accept-socket unit '%s': %m", value); diff --git a/src/shared/bpf-program.c b/src/shared/bpf-program.c index d5eb6f4ccb..f4bb7f390c 100644 --- a/src/shared/bpf-program.c +++ b/src/shared/bpf-program.c @@ -467,6 +467,9 @@ int bpf_program_deserialize_attachment(const char *v, FDSet *fds, BPFProgram **b return at; /* The rest is the path */ + if (isempty(v)) + return -EINVAL; + l = cunescape(v, 0, &unescaped); if (l < 0) return l; diff --git a/src/shared/varlink.c b/src/shared/varlink.c index 6b985a4c9b..808e2b2dba 100644 --- a/src/shared/varlink.c +++ b/src/shared/varlink.c @@ -3063,7 +3063,9 @@ int varlink_server_deserialize_one(VarlinkServer *s, const char *value, FDSet *f r = safe_atoi(buf, &fd); if (r < 0) return log_debug_errno(r, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf); - + if (fd < 0) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "VarlinkServerSocket varlink-server-socket-fd= has an invalid value: %d", fd); if (!fdset_contains(fds, fd)) return log_debug_errno(SYNTHETIC_ERRNO(EBADF), "VarlinkServerSocket varlink-server-socket-fd= has unknown fd %d: %m", fd); |