summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-05-03 21:45:26 +0900
committerGitHub <noreply@github.com>2023-05-03 21:45:26 +0900
commita76dc1f3a042adf203a79c34846563f5528b17bb (patch)
tree3532a8322f6d26e5c03435161335531195ecf4fe /src
parent406004a6c3fa38c1752056adf2ef59523e5ff534 (diff)
parent740831076cfcf2f73f3063fbb040c1ea593dfe6c (diff)
downloadsystemd-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.c38
-rw-r--r--src/core/meson.build7
-rw-r--r--src/core/service.c5
-rw-r--r--src/shared/bpf-program.c3
-rw-r--r--src/shared/varlink.c4
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);