summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build30
-rw-r--r--meson_options.txt2
-rw-r--r--src/basic/string-util.c28
-rw-r--r--src/basic/string-util.h1
-rw-r--r--src/fuzz/fuzz-bus-message.c47
-rw-r--r--src/fuzz/meson.build4
-rw-r--r--src/libsystemd/sd-bus/bus-dump.c10
-rw-r--r--src/libsystemd/sd-bus/bus-message.c313
-rw-r--r--src/libsystemd/sd-bus/bus-signature.c6
-rw-r--r--src/libsystemd/sd-bus/test-bus-gvariant.c19
-rw-r--r--src/libsystemd/sd-bus/test-bus-marshal.c14
-rw-r--r--src/libsystemd/sd-bus/test-bus-signature.c8
-rw-r--r--src/test/test-string-util.c62
-rw-r--r--test/fuzz-regressions/.gitattributes1
-rw-r--r--test/fuzz-regressions/meson.build43
-rw-r--r--test/fuzz/.gitattributes (renamed from test/fuzz-corpus/.gitattributes)0
-rw-r--r--test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56bin0 -> 157 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8ebin0 -> 51 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45bin0 -> 89 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70bin0 -> 534 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75bin0 -> 534 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54bin0 -> 143 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36bin0 -> 40 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084bin0 -> 32 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1ebin0 -> 93 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5bin0 -> 41 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5bin0 -> 28 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20bin0 -> 534 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/message1bin0 -> 534 bytes
-rw-r--r--test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5bbin0 -> 534 bytes
-rw-r--r--test/fuzz/fuzz-dhcp-server/discover-existing (renamed from test/fuzz-corpus/dhcp-server/discover-existing)bin248 -> 248 bytes
-rw-r--r--test/fuzz/fuzz-dhcp-server/discover-new (renamed from test/fuzz-corpus/dhcp-server/discover-new)bin247 -> 247 bytes
-rw-r--r--test/fuzz/fuzz-dhcp-server/release (renamed from test/fuzz-corpus/dhcp-server/release)bin248 -> 248 bytes
-rw-r--r--test/fuzz/fuzz-dhcp-server/request-existing (renamed from test/fuzz-corpus/dhcp-server/request-existing)bin260 -> 260 bytes
-rw-r--r--test/fuzz/fuzz-dhcp-server/request-new (renamed from test/fuzz-corpus/dhcp-server/request-new)bin259 -> 259 bytes
-rw-r--r--test/fuzz/fuzz-dhcp-server/request-reboot (renamed from test/fuzz-corpus/dhcp-server/request-reboot)bin254 -> 254 bytes
-rw-r--r--test/fuzz/fuzz-dhcp-server/request-renew (renamed from test/fuzz-corpus/dhcp-server/request-renew)bin248 -> 248 bytes
-rw-r--r--test/fuzz/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae (renamed from test/fuzz-regressions/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae)bin14 -> 14 bytes
-rw-r--r--test/fuzz/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef (renamed from test/fuzz-regressions/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef)bin9 -> 9 bytes
-rw-r--r--test/fuzz/fuzz-dns-packet/issue-7888 (renamed from test/fuzz-regressions/fuzz-dns-packet/issue-7888)bin25 -> 25 bytes
-rw-r--r--test/fuzz/fuzz-dns-packet/oss-fuzz-5465 (renamed from test/fuzz-regressions/fuzz-dns-packet/oss-fuzz-5465)bin24 -> 24 bytes
-rw-r--r--test/fuzz/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 (renamed from test/fuzz-regressions/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76)bin7675 -> 7675 bytes
-rw-r--r--test/fuzz/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 (renamed from test/fuzz-regressions/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45)bin2490 -> 2490 bytes
-rw-r--r--test/fuzz/fuzz-journal-remote/invalid-ts.txt (renamed from test/fuzz-corpus/journal-remote/invalid-ts.txt)bin4657 -> 4657 bytes
-rw-r--r--test/fuzz/fuzz-journal-remote/oss-fuzz-8659 (renamed from test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8659)0
-rw-r--r--test/fuzz/fuzz-journal-remote/oss-fuzz-8686 (renamed from test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8686)0
-rw-r--r--test/fuzz/fuzz-journal-remote/sample.txt (renamed from test/fuzz-corpus/journal-remote/sample.txt)0
-rw-r--r--test/fuzz/fuzz-journald-syslog/github-9795 (renamed from test/fuzz-regressions/fuzz-journald-syslog/github-9795)0
-rw-r--r--test/fuzz/fuzz-journald-syslog/github-9820 (renamed from test/fuzz-regressions/fuzz-journald-syslog/github-9820)0
-rw-r--r--test/fuzz/fuzz-journald-syslog/github-9827 (renamed from test/fuzz-regressions/fuzz-journald-syslog/github-9827)0
-rw-r--r--test/fuzz/fuzz-journald-syslog/github-9829 (renamed from test/fuzz-regressions/fuzz-journald-syslog/github-9829)0
-rw-r--r--test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 (renamed from test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1)bin53 -> 53 bytes
-rw-r--r--test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b (renamed from test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b)bin71 -> 71 bytes
-rw-r--r--test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\x2dswap.swap (renamed from test/fuzz-corpus/unit-file/dev-mapper-fedora_krowka\x2dswap.swap)0
-rw-r--r--test/fuzz/fuzz-unit-file/directives.service (renamed from test/fuzz-corpus/unit-file/directives.service)0
-rw-r--r--test/fuzz/fuzz-unit-file/empty.scope (renamed from test/fuzz-corpus/unit-file/empty.scope)0
-rw-r--r--test/fuzz/fuzz-unit-file/machine.slice (renamed from test/fuzz-corpus/unit-file/machine.slice)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-10007 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6884 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6884)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6885 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6885)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6886 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6886)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6892 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6892)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6897 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6897-evverx (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897-evverx)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6908 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6908)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6917 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6917)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6977 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-6977-unminimized (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-unminimized)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-7004 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-7004)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-8064 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064)0
-rw-r--r--test/fuzz/fuzz-unit-file/oss-fuzz-8827 (renamed from test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8827)0
-rw-r--r--test/fuzz/fuzz-unit-file/proc-sys-fs-binfmt_misc.automount (renamed from test/fuzz-corpus/unit-file/proc-sys-fs-binfmt_misc.automount)0
-rw-r--r--test/fuzz/fuzz-unit-file/syslog.socket (renamed from test/fuzz-corpus/unit-file/syslog.socket)0
-rw-r--r--test/fuzz/fuzz-unit-file/systemd-ask-password-console.path (renamed from test/fuzz-corpus/unit-file/systemd-ask-password-console.path)0
-rw-r--r--test/fuzz/fuzz-unit-file/systemd-machined.service (renamed from test/fuzz-corpus/unit-file/systemd-machined.service)0
-rw-r--r--test/fuzz/fuzz-unit-file/systemd-resolved.service (renamed from test/fuzz-corpus/unit-file/systemd-resolved.service)0
-rw-r--r--test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer (renamed from test/fuzz-corpus/unit-file/systemd-tmpfiles-clean.timer)0
-rw-r--r--test/fuzz/fuzz-unit-file/timers.target (renamed from test/fuzz-corpus/unit-file/timers.target)0
-rw-r--r--test/fuzz/fuzz-unit-file/var-lib-machines.mount (renamed from test/fuzz-corpus/unit-file/var-lib-machines.mount)0
-rw-r--r--test/fuzz/meson.build33
-rw-r--r--test/meson.build2
-rwxr-xr-xtools/oss-fuzz.sh6
82 files changed, 401 insertions, 228 deletions
diff --git a/meson.build b/meson.build
index 1c4febfa4b..02e230415d 100644
--- a/meson.build
+++ b/meson.build
@@ -781,6 +781,7 @@ conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
conf.set10('VALGRIND', get_option('valgrind'))
+conf.set10('LOG_TRACE', get_option('log-trace'))
#####################################################################
@@ -1476,7 +1477,7 @@ foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
module = tuple[0]
sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
- version_script_arg = join_paths(meson.current_source_dir(), sym)
+ version_script_arg = join_paths(meson.source_root(), sym)
nss = shared_library(
'nss_' + module,
@@ -1731,7 +1732,7 @@ if conf.get('ENABLE_LOGIND') == 1
public_programs += exe
if conf.get('HAVE_PAM') == 1
- version_script_arg = join_paths(meson.current_source_dir(), pam_systemd_sym)
+ version_script_arg = join_paths(meson.source_root(), pam_systemd_sym)
pam_systemd = shared_library(
'pam_systemd',
pam_systemd_c,
@@ -2847,9 +2848,7 @@ foreach tuple : sanitizers
test('@0@:@1@:@2@'.format(b, c, sanitizer),
env,
args : [exe.full_path(),
- join_paths(meson.source_root(),
- 'test/fuzz-regressions',
- p)])
+ join_paths(meson.source_root(), p)])
endif
endforeach
endif
@@ -2861,7 +2860,7 @@ endforeach
if git.found()
all_files = run_command(
git,
- ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
'ls-files',
':/*.[ch]'])
all_files = files(all_files.stdout().split())
@@ -2869,10 +2868,10 @@ if git.found()
custom_target(
'tags',
output : 'tags',
- command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files)
+ command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.source_root())] + all_files)
run_target(
'ctags',
- command : [env, 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files)
+ command : [env, 'ctags', '-o', '@0@/tags'.format(meson.source_root())] + all_files)
endif
if git.found()
@@ -2885,17 +2884,17 @@ endif
if git.found()
git_head = run_command(
git,
- ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
'rev-parse', 'HEAD']).stdout().strip()
git_head_short = run_command(
git,
- ['--git-dir=@0@/.git'.format(meson.current_source_dir()),
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
'rev-parse', '--short=7', 'HEAD']).stdout().strip()
run_target(
'git-snapshot',
command : ['git', 'archive',
- '-o', '@0@/systemd-@1@.tar.gz'.format(meson.current_source_dir(),
+ '-o', '@0@/systemd-@1@.tar.gz'.format(meson.source_root(),
git_head_short),
'--prefix', 'systemd-@0@/'.format(git_head),
'HEAD'])
@@ -3053,10 +3052,10 @@ foreach tuple : [
['blkid'],
['dbus'],
['glib'],
- ['nss-myhostname', conf.get('ENABLE_NSS_MYHOSTNAME') == 1],
- ['nss-mymachines', conf.get('ENABLE_NSS_MYMACHINES') == 1],
- ['nss-resolve', conf.get('ENABLE_NSS_RESOLVE') == 1],
- ['nss-systemd', conf.get('ENABLE_NSS_SYSTEMD') == 1],
+ ['nss-myhostname'],
+ ['nss-mymachines'],
+ ['nss-resolve'],
+ ['nss-systemd'],
['hwdb'],
['tpm'],
['man pages', want_man],
@@ -3072,6 +3071,7 @@ foreach tuple : [
['debug hashmap'],
['debug mmap cache'],
['valgrind', conf.get('VALGRIND') == 1],
+ ['trace logging', conf.get('LOG_TRACE') == 1],
]
if tuple.length() >= 2
diff --git a/meson_options.txt b/meson_options.txt
index 0407b97b5b..83ade5bea4 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -51,6 +51,8 @@ option('memory-accounting-default', type : 'boolean',
description : 'enable MemoryAccounting= by default')
option('valgrind', type : 'boolean', value : false,
description : 'do extra operations to avoid valgrind warnings')
+option('log-trace', type : 'boolean', value : false,
+ description : 'enable low level debug logging')
option('utmp', type : 'boolean',
description : 'support for utmp/wtmp log handling')
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 0a40683493..dfa739996f 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -1004,7 +1004,7 @@ int free_and_strdup(char **p, const char *s) {
assert(p);
- /* Replaces a string pointer with an strdup()ed new string,
+ /* Replaces a string pointer with a strdup()ed new string,
* possibly freeing the old one. */
if (streq_ptr(*p, s))
@@ -1023,6 +1023,32 @@ int free_and_strdup(char **p, const char *s) {
return 1;
}
+int free_and_strndup(char **p, const char *s, size_t l) {
+ char *t;
+
+ assert(p);
+ assert(s || l == 0);
+
+ /* Replaces a string pointer with a strndup()ed new string,
+ * freeing the old one. */
+
+ if (!*p && !s)
+ return 0;
+
+ if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0'))
+ return 0;
+
+ if (s) {
+ t = strndup(s, l);
+ if (!t)
+ return -ENOMEM;
+ } else
+ t = NULL;
+
+ free_and_replace(*p, t);
+ return 1;
+}
+
#if !HAVE_EXPLICIT_BZERO
/*
* Pointer to memset is volatile so that compiler must de-reference
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index fcd12f3a30..72c075aa39 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -176,6 +176,7 @@ char *strrep(const char *s, unsigned n);
int split_pair(const char *s, const char *sep, char **l, char **r);
int free_and_strdup(char **p, const char *s);
+int free_and_strndup(char **p, const char *s, size_t l);
/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
diff --git a/src/fuzz/fuzz-bus-message.c b/src/fuzz/fuzz-bus-message.c
new file mode 100644
index 0000000000..9842c62a6f
--- /dev/null
+++ b/src/fuzz/fuzz-bus-message.c
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "alloc-util.h"
+#include "bus-dump.h"
+#include "bus-message.h"
+#include "env-util.h"
+#include "fd-util.h"
+#include "fuzz.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ _cleanup_free_ char *out = NULL; /* out should be freed after g */
+ size_t out_size;
+ _cleanup_fclose_ FILE *g = NULL;
+ _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ _cleanup_free_ void *buffer = NULL;
+ 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);
+
+ r = sd_bus_new(&bus);
+ assert_se(r >= 0);
+
+ assert_se(buffer = memdup(data, size));
+
+ r = bus_message_from_malloc(bus, buffer, size, NULL, 0, NULL, &m);
+ if (r == -EBADMSG)
+ return 0;
+ assert_se(r >= 0);
+ TAKE_PTR(buffer);
+
+ if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0)
+ assert_se(g = open_memstream(&out, &out_size));
+
+ bus_message_dump(m, g ?: stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
+
+ r = sd_bus_message_rewind(m, true);
+ assert_se(r >= 0);
+
+ return 0;
+}
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
index 066737c175..31ee41cbe0 100644
--- a/src/fuzz/meson.build
+++ b/src/fuzz/meson.build
@@ -1,6 +1,10 @@
# SPDX-License-Identifier: LGPL-2.1+
fuzzers += [
+ [['src/fuzz/fuzz-bus-message.c'],
+ [libshared],
+ []],
+
[['src/fuzz/fuzz-dns-packet.c',
dns_type_headers],
[libsystemd_resolve_core,
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index 888f161768..506ed0d73c 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -57,8 +57,14 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
"%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
- m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", special_glyph(TRIANGULAR_BULLET), ansi_normal(),
- ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(),
+ m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "",
+ special_glyph(TRIANGULAR_BULLET),
+ ansi_normal(),
+
+ ansi_highlight(),
+ bus_message_type_to_string(m->header->type) ?: "(unknown)",
+ ansi_normal(),
+
m->header->endian,
m->header->flags,
m->header->version,
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 6e404367db..697553e74e 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -75,19 +75,38 @@ static void message_reset_parts(sd_bus_message *m) {
m->cached_rindex_part_begin = 0;
}
-static void message_reset_containers(sd_bus_message *m) {
- unsigned i;
+static struct bus_container *message_get_last_container(sd_bus_message *m) {
+ assert(m);
+
+ if (m->n_containers == 0)
+ return &m->root_container;
+
+ assert(m->containers);
+ return m->containers + m->n_containers - 1;
+}
+
+static void message_free_last_container(sd_bus_message *m) {
+ struct bus_container *c;
+ c = message_get_last_container(m);
+
+ free(c->signature);
+ free(c->peeked_signature);
+ free(c->offsets);
+
+ /* Move to previous container, but not if we are on root container */
+ if (m->n_containers > 0)
+ m->n_containers--;
+}
+
+static void message_reset_containers(sd_bus_message *m) {
assert(m);
- for (i = 0; i < m->n_containers; i++) {
- free(m->containers[i].signature);
- free(m->containers[i].offsets);
- }
+ while (m->n_containers > 0)
+ message_free_last_container(m);
m->containers = mfree(m->containers);
-
- m->n_containers = m->containers_allocated = 0;
+ m->containers_allocated = 0;
m->root_container.index = 0;
}
@@ -110,10 +129,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
free(m->iovec);
message_reset_containers(m);
- free(m->root_container.signature);
- free(m->root_container.offsets);
-
- free(m->root_container.peeked_signature);
+ assert(m->n_containers == 0);
+ message_free_last_container(m);
bus_creds_done(&m->creds);
return mfree(m);
@@ -208,7 +225,7 @@ static int message_append_field_string(
/* dbus1 doesn't allow strings over 32bit, let's enforce this
* globally, to not risk convertability */
l = strlen(s);
- if (l > (size_t) (uint32_t) -1)
+ if (l > UINT32_MAX)
return -EINVAL;
/* Signature "(yv)" where the variant contains "s" */
@@ -1088,16 +1105,6 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *
return 0;
}
-static struct bus_container *message_get_container(sd_bus_message *m) {
- assert(m);
-
- if (m->n_containers == 0)
- return &m->root_container;
-
- assert(m->containers);
- return m->containers + m->n_containers - 1;
-}
-
struct bus_body_part *message_append_part(sd_bus_message *m) {
struct bus_body_part *part;
@@ -1188,7 +1195,7 @@ static int message_add_offset(sd_bus_message *m, size_t offset) {
/* Add offset to current container, unless this is the first
* item in it, which will have the 0 offset, which we can
* ignore. */
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (!c->need_offsets)
return 0;
@@ -1360,7 +1367,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
assert_return(bus_type_is_basic(type), -EINVAL);
assert_return(!m->poisoned, -ESTALE);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature && c->signature[c->index]) {
/* Container signature is already set */
@@ -1553,7 +1560,7 @@ _public_ int sd_bus_message_append_string_space(
assert_return(!m->sealed, -EPERM);
assert_return(!m->poisoned, -ESTALE);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature && c->signature[c->index]) {
/* Container signature is already set */
@@ -1924,7 +1931,7 @@ _public_ int sd_bus_message_open_container(
char type,
const char *contents) {
- struct bus_container *c, *w;
+ struct bus_container *c;
uint32_t *array_size = NULL;
_cleanup_free_ char *signature = NULL;
size_t before, begin = 0;
@@ -1942,7 +1949,7 @@ _public_ int sd_bus_message_open_container(
return -ENOMEM;
}
- c = message_get_container(m);
+ c = message_get_last_container(m);
signature = strdup(contents);
if (!signature) {
@@ -1969,16 +1976,14 @@ _public_ int sd_bus_message_open_container(
return r;
/* OK, let's fill it in */
- w = m->containers + m->n_containers++;
- w->enclosing = type;
- w->signature = TAKE_PTR(signature);
- w->index = 0;
- w->array_size = array_size;
- w->before = before;
- w->begin = begin;
- w->n_offsets = w->offsets_allocated = 0;
- w->offsets = NULL;
- w->need_offsets = need_offsets;
+ m->containers[m->n_containers++] = (struct bus_container) {
+ .enclosing = type,
+ .signature = TAKE_PTR(signature),
+ .array_size = array_size,
+ .before = before,
+ .begin = begin,
+ .need_offsets = need_offsets,
+ };
return 0;
}
@@ -2169,7 +2174,7 @@ _public_ int sd_bus_message_close_container(sd_bus_message *m) {
assert_return(m->n_containers > 0, -EINVAL);
assert_return(!m->poisoned, -ESTALE);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->enclosing != SD_BUS_TYPE_ARRAY)
if (c->signature && c->signature[c->index] != 0)
@@ -2439,11 +2444,6 @@ _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
va_list ap;
int r;
- assert_return(m, -EINVAL);
- assert_return(types, -EINVAL);
- assert_return(!m->sealed, -EPERM);
- assert_return(!m->poisoned, -ESTALE);
-
va_start(ap, types);
r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
@@ -2673,7 +2673,7 @@ _public_ int sd_bus_message_append_string_memfd(
if (size > (uint64_t) (uint32_t) -1)
return -EINVAL;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature && c->signature[c->index]) {
/* Container signature is already set */
@@ -3006,7 +3006,7 @@ static bool message_end_of_signature(sd_bus_message *m) {
assert(m);
- c = message_get_container(m);
+ c = message_get_last_container(m);
return !c->signature || c->signature[c->index] == 0;
}
@@ -3015,7 +3015,7 @@ static bool message_end_of_array(sd_bus_message *m, size_t index) {
assert(m);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->enclosing != SD_BUS_TYPE_ARRAY)
return false;
@@ -3110,6 +3110,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
assert(alignment > 0);
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
+ assert(c->offsets[c->offset_index+1] >= *rindex);
c->item_size = c->offsets[c->offset_index+1] - *rindex;
} else {
@@ -3149,6 +3150,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
assert(alignment > 0);
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
+ assert(c->offsets[c->offset_index+1] >= *rindex);
c->item_size = c->offsets[c->offset_index+1] - *rindex;
c->offset_index++;
@@ -3276,7 +3278,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (message_end_of_array(m, m->rindex))
return 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature[c->index] != type)
return -ENXIO;
@@ -3287,6 +3289,12 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
bool ok;
+ /* D-Bus spec: The marshalling formats for the string-like types all end
+ * with a single zero (NUL) byte, but that byte is not considered to be part
+ * of the text. */
+ if (c->item_size == 0)
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, c->item_size, &q);
if (r < 0)
return r;
@@ -3381,6 +3389,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
return r;
l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
+ if (l == UINT32_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -3403,6 +3415,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -3494,7 +3510,7 @@ static int bus_message_enter_array(
size_t rindex;
void *q;
- int r, alignment;
+ int r;
assert(m);
assert(c);
@@ -3520,6 +3536,7 @@ static int bus_message_enter_array(
if (!BUS_MESSAGE_IS_GVARIANT(m)) {
/* dbus1 */
+ int alignment;
r = message_peek_body(m, &rindex, 4, 4, &q);
if (r < 0)
@@ -3553,7 +3570,8 @@ static int bus_message_enter_array(
*n_offsets = 0;
} else {
- size_t where, p = 0, framing, sz;
+ size_t where, previous = 0, framing, sz;
+ int alignment;
unsigned i;
/* gvariant: variable length array */
@@ -3581,17 +3599,22 @@ static int bus_message_enter_array(
if (!*offsets)
return -ENOMEM;
+ alignment = bus_gvariant_get_alignment(c->signature);
+ assert(alignment > 0);
+
for (i = 0; i < *n_offsets; i++) {
- size_t x;
+ size_t x, start;
+
+ start = ALIGN_TO(previous, alignment);
x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
if (x > c->item_size - sz)
return -EBADMSG;
- if (x < p)
+ if (x < start)
return -EBADMSG;
(*offsets)[i] = rindex + x;
- p = x;
+ previous = x;
}
*item_size = (*offsets)[0] - rindex;
@@ -3661,6 +3684,10 @@ static int bus_message_enter_variant(
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -3689,7 +3716,7 @@ static int build_struct_offsets(
size_t *n_offsets) {
unsigned n_variable = 0, n_total = 0, v;
- size_t previous = 0, where;
+ size_t previous, where;
const char *p;
size_t sz;
void *q;
@@ -3768,6 +3795,7 @@ static int build_struct_offsets(
/* Second, loop again and build an offset table */
p = signature;
+ previous = m->rindex;
while (*p != 0) {
size_t n, offset;
int k;
@@ -3781,37 +3809,37 @@ static int build_struct_offsets(
memcpy(t, p, n);
t[n] = 0;
+ size_t align = bus_gvariant_get_alignment(t);
+ assert(align > 0);
+
+ /* The possible start of this member after including alignment */
+ size_t start = ALIGN_TO(previous, align);
+
k = bus_gvariant_get_size(t);
if (k < 0) {
size_t x;
- /* variable size */
+ /* Variable size */
if (v > 0) {
v--;
x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
if (x >= size)
return -EBADMSG;
- if (m->rindex + x < previous)
- return -EBADMSG;
} else
- /* The last item's end
- * is determined from
- * the start of the
- * offset array */
+ /* The last item's end is determined
+ * from the start of the offset array */
x = size - (n_variable * sz);
offset = m->rindex + x;
-
- } else {
- size_t align;
-
- /* fixed size */
- align = bus_gvariant_get_alignment(t);
- assert(align > 0);
-
- offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
- }
+ if (offset < start) {
+ log_debug("For type %s with alignment %zu, message specifies offset %zu which is smaller than previous end %zu + alignment = %zu",
+ t, align, offset, previous, start);
+ return -EBADMSG;
+ }
+ } else
+ /* Fixed size */
+ offset = start + k;
}
previous = (*offsets)[(*n_offsets)++] = offset;
@@ -3941,10 +3969,10 @@ static int bus_message_enter_dict_entry(
_public_ int sd_bus_message_enter_container(sd_bus_message *m,
char type,
const char *contents) {
- struct bus_container *c, *w;
+ struct bus_container *c;
uint32_t *array_size = NULL;
_cleanup_free_ char *signature = NULL;
- size_t before;
+ size_t before, end;
_cleanup_free_ size_t *offsets = NULL;
size_t n_offsets = 0, item_size = 0;
int r;
@@ -4000,7 +4028,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
if (message_end_of_array(m, m->rindex))
return 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
signature = strdup(contents);
if (!signature)
@@ -4023,28 +4051,26 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
return r;
/* OK, let's fill it in */
- w = m->containers + m->n_containers++;
- w->enclosing = type;
- w->signature = TAKE_PTR(signature);
- w->peeked_signature = NULL;
- w->index = 0;
-
- w->before = before;
- w->begin = m->rindex;
-
- /* Unary type has fixed size of 1, but virtual size of 0 */
if (BUS_MESSAGE_IS_GVARIANT(m) &&
type == SD_BUS_TYPE_STRUCT &&
isempty(signature))
- w->end = m->rindex + 0;
+ end = m->rindex + 0;
else
- w->end = m->rindex + c->item_size;
-
- w->array_size = array_size;
- w->item_size = item_size;
- w->offsets = TAKE_PTR(offsets);
- w->n_offsets = n_offsets;
- w->offset_index = 0;
+ end = m->rindex + c->item_size;
+
+ m->containers[m->n_containers++] = (struct bus_container) {
+ .enclosing = type,
+ .signature = TAKE_PTR(signature),
+
+ .before = before,
+ .begin = m->rindex,
+ /* Unary type has fixed size of 1, but virtual size of 0 */
+ .end = end,
+ .array_size = array_size,
+ .item_size = item_size,
+ .offsets = TAKE_PTR(offsets),
+ .n_offsets = n_offsets,
+ };
return 1;
}
@@ -4058,7 +4084,7 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
assert_return(m->sealed, -EPERM);
assert_return(m->n_containers > 0, -ENXIO);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->enclosing != SD_BUS_TYPE_ARRAY) {
if (c->signature && c->signature[c->index] != 0)
@@ -4077,13 +4103,9 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
return -EBUSY;
}
- free(c->signature);
- free(c->peeked_signature);
- free(c->offsets);
- m->n_containers--;
-
- c = message_get_container(m);
+ message_free_last_container(m);
+ c = message_get_last_container(m);
saved = c->index;
c->index = c->saved_index;
r = container_next_item(m, c, &m->rindex);
@@ -4101,19 +4123,16 @@ static void message_quit_container(sd_bus_message *m) {
assert(m->sealed);
assert(m->n_containers > 0);
- c = message_get_container(m);
-
/* Undo seeks */
+ c = message_get_last_container(m);
assert(m->rindex >= c->before);
m->rindex = c->before;
/* Free container */
- free(c->signature);
- free(c->offsets);
- m->n_containers--;
+ message_free_last_container(m);
/* Correct index of new top-level container */
- c = message_get_container(m);
+ c = message_get_last_container(m);
c->index = c->saved_index;
}
@@ -4130,7 +4149,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (message_end_of_array(m, m->rindex))
goto eof;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (bus_type_is_basic(c->signature[c->index])) {
if (contents)
@@ -4144,20 +4163,20 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index+1, &l);
if (r < 0)
return r;
- assert(l >= 1);
+ /* signature_element_length does verification internally */
- sig = strndup(c->signature + c->index + 1, l);
- if (!sig)
+ /* The array element must not be empty */
+ assert(l >= 1);
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4170,19 +4189,17 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index, &l);
if (r < 0)
return r;
- assert(l >= 2);
- sig = strndup(c->signature + c->index + 1, l - 2);
- if (!sig)
+ assert(l >= 3);
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l - 2) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4222,9 +4239,8 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (k > c->item_size)
return -EBADMSG;
- free(c->peeked_signature);
- c->peeked_signature = strndup((char*) q + 1, k - 1);
- if (!c->peeked_signature)
+ if (free_and_strndup(&c->peeked_signature,
+ (char*) q + 1, k - 1) < 0)
return -ENOMEM;
if (!signature_is_valid(c->peeked_signature, true))
@@ -4240,6 +4256,10 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -4277,11 +4297,10 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
message_reset_containers(m);
m->rindex = 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
} else {
- c = message_get_container(m);
+ c = message_get_last_container(m);
- c->offset_index = 0;
c->index = 0;
m->rindex = c->begin;
}
@@ -4496,10 +4515,6 @@ _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
va_list ap;
int r;
- assert_return(m, -EINVAL);
- assert_return(m->sealed, -EPERM);
- assert_return(types, -EINVAL);
-
va_start(ap, types);
r = sd_bus_message_readv(m, types, ap);
va_end(ap);
@@ -4524,7 +4539,7 @@ _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
if (message_end_of_array(m, m->rindex))
return 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
r = signature_element_length(c->signature + c->index, &l);
if (r < 0)
@@ -4690,7 +4705,7 @@ _public_ int sd_bus_message_read_array(
if (r <= 0)
return r;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (BUS_MESSAGE_IS_GVARIANT(m)) {
align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
@@ -4827,6 +4842,10 @@ static int message_peek_field_string(
if (r < 0)
return r;
+ if (l == UINT32_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_fields(m, ri, 1, l+1, &q);
if (r < 0)
return r;
@@ -4878,6 +4897,10 @@ static int message_peek_field_signature(
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_fields(m, ri, 1, l+1, &q);
if (r < 0)
return r;
@@ -4959,18 +4982,18 @@ static int message_skip_fields(
} else if (t == SD_BUS_TYPE_ARRAY) {
- r = signature_element_length(*signature+1, &l);
+ r = signature_element_length(*signature + 1, &l);
if (r < 0)
return r;
assert(l >= 1);
{
- char sig[l-1], *s;
+ char sig[l + 1], *s = sig;
uint32_t nas;
int alignment;
- strncpy(sig, *signature + 1, l-1);
- s = sig;
+ strncpy(sig, *signature + 1, l);
+ sig[l] = '\0';
alignment = bus_type_get_alignment(sig[0]);
if (alignment < 0)
@@ -5014,9 +5037,9 @@ static int message_skip_fields(
assert(l >= 2);
{
- char sig[l-1], *s;
- strncpy(sig, *signature + 1, l-1);
- s = sig;
+ char sig[l + 1], *s = sig;
+ strncpy(sig, *signature + 1, l);
+ sig[l] = '\0';
r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
if (r < 0)
@@ -5025,7 +5048,7 @@ static int message_skip_fields(
*signature += l;
} else
- return -EINVAL;
+ return -EBADMSG;
}
}
@@ -5056,25 +5079,21 @@ int bus_message_parse_fields(sd_bus_message *m) {
if (*p == 0) {
size_t l;
- char *c;
/* We found the beginning of the signature
* string, yay! We require the body to be a
* structure, so verify it and then strip the
* opening/closing brackets. */
- l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
+ l = (char*) m->footer + m->footer_accessible - p - (1 + sz);
if (l < 2 ||
p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
return -EBADMSG;
- c = strndup(p + 1 + 1, l - 2);
- if (!c)
+ if (free_and_strndup(&m->root_container.signature,
+ p + 1 + 1, l - 2) < 0)
return -ENOMEM;
-
- free(m->root_container.signature);
- m->root_container.signature = c;
break;
}
@@ -5396,6 +5415,8 @@ int bus_message_parse_fields(sd_bus_message *m) {
&m->root_container.item_size,
&m->root_container.offsets,
&m->root_container.n_offsets);
+ if (r == -EINVAL)
+ return -EBADMSG;
if (r < 0)
return r;
}
@@ -5591,7 +5612,7 @@ _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complet
assert_return(m, NULL);
- c = complete ? &m->root_container : message_get_container(m);
+ c = complete ? &m->root_container : message_get_last_container(m);
return strempty(c->signature);
}
diff --git a/src/libsystemd/sd-bus/bus-signature.c b/src/libsystemd/sd-bus/bus-signature.c
index 06ef1ee4cb..1ecd6e8b7e 100644
--- a/src/libsystemd/sd-bus/bus-signature.c
+++ b/src/libsystemd/sd-bus/bus-signature.c
@@ -56,6 +56,12 @@ static int signature_element_length_internal(
p += t;
}
+ if (p - s < 2)
+ /* D-Bus spec: Empty structures are not allowed; there
+ * must be at least one type code between the parentheses.
+ */
+ return -EINVAL;
+
*l = p - s + 1;
return 0;
}
diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c
index 92324bff29..1a9a35d56b 100644
--- a/src/libsystemd/sd-bus/test-bus-gvariant.c
+++ b/src/libsystemd/sd-bus/test-bus-gvariant.c
@@ -17,8 +17,10 @@
#include "util.h"
static void test_bus_gvariant_is_fixed_size(void) {
+ log_info("/* %s */", __func__);
+
assert_se(bus_gvariant_is_fixed_size("") > 0);
- assert_se(bus_gvariant_is_fixed_size("()") > 0);
+ assert_se(bus_gvariant_is_fixed_size("()") == -EINVAL);
assert_se(bus_gvariant_is_fixed_size("y") > 0);
assert_se(bus_gvariant_is_fixed_size("u") > 0);
assert_se(bus_gvariant_is_fixed_size("b") > 0);
@@ -42,8 +44,10 @@ static void test_bus_gvariant_is_fixed_size(void) {
}
static void test_bus_gvariant_get_size(void) {
+ log_info("/* %s */", __func__);
+
assert_se(bus_gvariant_get_size("") == 0);
- assert_se(bus_gvariant_get_size("()") == 1);
+ assert_se(bus_gvariant_get_size("()") == -EINVAL);
assert_se(bus_gvariant_get_size("y") == 1);
assert_se(bus_gvariant_get_size("u") == 4);
assert_se(bus_gvariant_get_size("b") == 1);
@@ -74,8 +78,10 @@ static void test_bus_gvariant_get_size(void) {
}
static void test_bus_gvariant_get_alignment(void) {
+ log_info("/* %s */", __func__);
+
assert_se(bus_gvariant_get_alignment("") == 1);
- assert_se(bus_gvariant_get_alignment("()") == 1);
+ assert_se(bus_gvariant_get_alignment("()") == -EINVAL);
assert_se(bus_gvariant_get_alignment("y") == 1);
assert_se(bus_gvariant_get_alignment("b") == 1);
assert_se(bus_gvariant_get_alignment("u") == 4);
@@ -129,7 +135,10 @@ static int test_marshal(void) {
bus->message_version = 2; /* dirty hack to enable gvariant */
- assert_se(sd_bus_message_new_method_call(bus, &m, "a.service.name", "/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works", "an.interface.name", "AMethodName") >= 0);
+ r = sd_bus_message_new_method_call(bus, &m, "a.service.name",
+ "/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works",
+ "an.interface.name", "AMethodName");
+ assert_se(r >= 0);
assert_cc(sizeof(struct bus_header) == 16);
@@ -202,7 +211,7 @@ static int test_marshal(void) {
}
int main(int argc, char *argv[]) {
- test_setup_logging(LOG_INFO);
+ test_setup_logging(LOG_DEBUG);
test_bus_gvariant_is_fixed_size();
test_bus_gvariant_get_size();
diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c
index 020a5e51e5..d1c674b223 100644
--- a/src/libsystemd/sd-bus/test-bus-marshal.c
+++ b/src/libsystemd/sd-bus/test-bus-marshal.c
@@ -18,8 +18,8 @@
#include "bus-label.h"
#include "bus-message.h"
#include "bus-util.h"
+#include "escape.h"
#include "fd-util.h"
-#include "hexdecoct.h"
#include "log.h"
#include "tests.h"
#include "util.h"
@@ -111,7 +111,7 @@ int main(int argc, char *argv[]) {
uint8_t u, v;
void *buffer = NULL;
size_t sz;
- char *h;
+ _cleanup_free_ char *h = NULL;
const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
char *s;
_cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
@@ -154,7 +154,7 @@ int main(int argc, char *argv[]) {
assert_se(r >= 0);
r = sd_bus_message_append(m, "()");
- assert_se(r >= 0);
+ assert_se(r == -EINVAL);
r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
assert_se(r >= 0);
@@ -197,11 +197,9 @@ int main(int argc, char *argv[]) {
r = bus_message_get_blob(m, &buffer, &sz);
assert_se(r >= 0);
- h = hexmem(buffer, sz);
+ h = cescape_length(buffer, sz);
assert_se(h);
-
log_info("message size = %zu, contents =\n%s", sz, h);
- free(h);
#if HAVE_GLIB
#ifndef __SANITIZE_ADDRESS__
@@ -298,7 +296,7 @@ int main(int argc, char *argv[]) {
assert_se(v == 10);
r = sd_bus_message_read(m, "()");
- assert_se(r > 0);
+ assert_se(r < 0);
r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
assert_se(r > 0);
@@ -379,7 +377,7 @@ int main(int argc, char *argv[]) {
assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
- r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
+ r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y");
assert_se(r >= 0);
assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c
index ab59d04e20..84648dbc2a 100644
--- a/src/libsystemd/sd-bus/test-bus-signature.c
+++ b/src/libsystemd/sd-bus/test-bus-signature.c
@@ -14,9 +14,9 @@ int main(int argc, char *argv[]) {
assert_se(signature_is_single("v", false));
assert_se(signature_is_single("as", false));
assert_se(signature_is_single("(ss)", false));
- assert_se(signature_is_single("()", false));
- assert_se(signature_is_single("(()()()()())", false));
- assert_se(signature_is_single("(((())))", false));
+ assert_se(!signature_is_single("()", false));
+ assert_se(!signature_is_single("(()()()()())", false));
+ assert_se(!signature_is_single("(((())))", false));
assert_se(signature_is_single("((((s))))", false));
assert_se(signature_is_single("{ss}", true));
assert_se(signature_is_single("a{ss}", false));
@@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas", false));
assert_se(!signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau", false));
- assert_se(signature_is_valid("(((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))", false));
+ assert_se(signature_is_valid("((((((((((((((((((((((((((((((((s))))))))))))))))))))))))))))))))", false));
assert_se(!signature_is_valid("((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))", false));
assert_se(namespace_complex_pattern("", ""));
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index a9f261839c..8c1f91d4ef 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -5,6 +5,7 @@
#include "macro.h"
#include "string-util.h"
#include "strv.h"
+#include "tests.h"
#include "utf8.h"
static void test_string_erase(void) {
@@ -30,6 +31,64 @@ static void test_string_erase(void) {
assert_se(x[9] == '\0');
}
+static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) {
+ int r;
+
+ log_debug("%s: \"%s\", \"%s\", %zd (expect \"%s\", %s)",
+ __func__, strnull(*t), strnull(src), l, strnull(expected), yes_no(change));
+
+ r = free_and_strndup(t, src, l);
+ assert_se(streq_ptr(*t, expected));
+ assert_se(r == change); /* check that change occurs only when necessary */
+}
+
+static void test_free_and_strndup(void) {
+ static const struct test_case {
+ const char *src;
+ size_t len;
+ const char *expected;
+ } cases[] = {
+ {"abc", 0, ""},
+ {"abc", 0, ""},
+ {"abc", 1, "a"},
+ {"abc", 2, "ab"},
+ {"abc", 3, "abc"},
+ {"abc", 4, "abc"},
+ {"abc", 5, "abc"},
+ {"abc", 5, "abc"},
+ {"abc", 4, "abc"},
+ {"abc", 3, "abc"},
+ {"abc", 2, "ab"},
+ {"abc", 1, "a"},
+ {"abc", 0, ""},
+
+ {"", 0, ""},
+ {"", 1, ""},
+ {"", 2, ""},
+ {"", 0, ""},
+ {"", 1, ""},
+ {"", 2, ""},
+ {"", 2, ""},
+ {"", 1, ""},
+ {"", 0, ""},
+
+ {NULL, 0, NULL},
+
+ {"foo", 3, "foo"},
+ {"foobar", 6, "foobar"},
+ };
+
+ _cleanup_free_ char *t = NULL;
+ const char *prev_expected = t;
+
+ for (unsigned i = 0; i < ELEMENTSOF(cases); i++) {
+ test_free_and_strndup_one(&t,
+ cases[i].src, cases[i].len, cases[i].expected,
+ !streq_ptr(cases[i].expected, prev_expected));
+ prev_expected = t;
+ }
+}
+
static void test_ascii_strcasecmp_n(void) {
assert_se(ascii_strcasecmp_n("", "", 0) == 0);
@@ -520,7 +579,10 @@ static void test_memory_startswith_no_case(void) {
}
int main(int argc, char *argv[]) {
+ test_setup_logging(LOG_DEBUG);
+
test_string_erase();
+ test_free_and_strndup();
test_ascii_strcasecmp_n();
test_ascii_strcasecmp_nn();
test_cellescape();
diff --git a/test/fuzz-regressions/.gitattributes b/test/fuzz-regressions/.gitattributes
deleted file mode 100644
index 7b1b3e1835..0000000000
--- a/test/fuzz-regressions/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-/*/* -whitespace
diff --git a/test/fuzz-regressions/meson.build b/test/fuzz-regressions/meson.build
deleted file mode 100644
index 043d3f3154..0000000000
--- a/test/fuzz-regressions/meson.build
+++ /dev/null
@@ -1,43 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1+
-
-sanitize_address = custom_target(
- 'sanitize-address-fuzzers',
- output : 'sanitize-address-fuzzers',
- command : [meson_build_sh,
- meson.source_root(),
- '@OUTPUT@',
- 'fuzzers',
- '-Db_lundef=false -Db_sanitize=address'])
-
-sanitizers = [['address', sanitize_address]]
-
-fuzz_regression_tests = '''
- fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae
- fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef
- fuzz-dns-packet/issue-7888
- fuzz-dns-packet/oss-fuzz-5465
- fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76
- fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45
- fuzz-journal-remote/oss-fuzz-8659
- fuzz-journal-remote/oss-fuzz-8686
- fuzz-journald-syslog/github-9795
- fuzz-journald-syslog/github-9820
- fuzz-journald-syslog/github-9827
- fuzz-journald-syslog/github-9829
- fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1
- fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b
- fuzz-unit-file/oss-fuzz-6884
- fuzz-unit-file/oss-fuzz-6885
- fuzz-unit-file/oss-fuzz-6886
- fuzz-unit-file/oss-fuzz-6892
- fuzz-unit-file/oss-fuzz-6897
- fuzz-unit-file/oss-fuzz-6897-evverx
- fuzz-unit-file/oss-fuzz-6908
- fuzz-unit-file/oss-fuzz-6917
- fuzz-unit-file/oss-fuzz-6977
- fuzz-unit-file/oss-fuzz-6977-unminimized
- fuzz-unit-file/oss-fuzz-7004
- fuzz-unit-file/oss-fuzz-8064
- fuzz-unit-file/oss-fuzz-8827
- fuzz-unit-file/oss-fuzz-10007
-'''.split()
diff --git a/test/fuzz-corpus/.gitattributes b/test/fuzz/.gitattributes
index 7b1b3e1835..7b1b3e1835 100644
--- a/test/fuzz-corpus/.gitattributes
+++ b/test/fuzz/.gitattributes
diff --git a/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 b/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56
new file mode 100644
index 0000000000..f1bf3229ef
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e b/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e
new file mode 100644
index 0000000000..4488f0a6c6
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45 b/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45
new file mode 100644
index 0000000000..aa0c6ff7f7
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-32bf69483cbd4f2e6d46c25a2f92a472109aee45
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70 b/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70
new file mode 100644
index 0000000000..6a20265a39
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-37449529b1ad867f0c2671fa80aca5d7812a2b70
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75 b/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75
new file mode 100644
index 0000000000..5faf3308e7
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-4162a61a79e4c5a832ca5232212f75fa560a1f75
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54 b/test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54
new file mode 100644
index 0000000000..865b29507c
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-4f0211eb269e28db941961061494bfdbf3345e54
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36 b/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36
new file mode 100644
index 0000000000..b3fee9e07a
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-603dfd98252375ac7dbced53c2ec312671939a36
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 b/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084
new file mode 100644
index 0000000000..52469650b5
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e b/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e
new file mode 100644
index 0000000000..2ae1a8715a
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-c1b37b4729b42c0c05b23cba4eed5d8102498a1e
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5 b/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5
new file mode 100644
index 0000000000..26262e1149
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-d8f3941c74219b4c03532c9b244d5ea539c61af5
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5 b/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5
new file mode 100644
index 0000000000..9d3fa0035f
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/crash-e1b811da5ca494e494b77c6bd8e1c2f2989425c5
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 b/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
new file mode 100644
index 0000000000..c371824ffb
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/message1 b/test/fuzz/fuzz-bus-message/message1
new file mode 100644
index 0000000000..2df70fd7cb
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/message1
Binary files differ
diff --git a/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b b/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b
new file mode 100644
index 0000000000..c975f906ee
--- /dev/null
+++ b/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b
Binary files differ
diff --git a/test/fuzz-corpus/dhcp-server/discover-existing b/test/fuzz/fuzz-dhcp-server/discover-existing
index 1e26bf09e2..1e26bf09e2 100644
--- a/test/fuzz-corpus/dhcp-server/discover-existing
+++ b/test/fuzz/fuzz-dhcp-server/discover-existing
Binary files differ
diff --git a/test/fuzz-corpus/dhcp-server/discover-new b/test/fuzz/fuzz-dhcp-server/discover-new
index feeae55e5e..feeae55e5e 100644
--- a/test/fuzz-corpus/dhcp-server/discover-new
+++ b/test/fuzz/fuzz-dhcp-server/discover-new
Binary files differ
diff --git a/test/fuzz-corpus/dhcp-server/release b/test/fuzz/fuzz-dhcp-server/release
index 4f3eadb2f2..4f3eadb2f2 100644
--- a/test/fuzz-corpus/dhcp-server/release
+++ b/test/fuzz/fuzz-dhcp-server/release
Binary files differ
diff --git a/test/fuzz-corpus/dhcp-server/request-existing b/test/fuzz/fuzz-dhcp-server/request-existing
index 9f7a0d88f7..9f7a0d88f7 100644
--- a/test/fuzz-corpus/dhcp-server/request-existing
+++ b/test/fuzz/fuzz-dhcp-server/request-existing
Binary files differ
diff --git a/test/fuzz-corpus/dhcp-server/request-new b/test/fuzz/fuzz-dhcp-server/request-new
index fc6f5864a7..fc6f5864a7 100644
--- a/test/fuzz-corpus/dhcp-server/request-new
+++ b/test/fuzz/fuzz-dhcp-server/request-new
Binary files differ
diff --git a/test/fuzz-corpus/dhcp-server/request-reboot b/test/fuzz/fuzz-dhcp-server/request-reboot
index fde74b2b91..fde74b2b91 100644
--- a/test/fuzz-corpus/dhcp-server/request-reboot
+++ b/test/fuzz/fuzz-dhcp-server/request-reboot
Binary files differ
diff --git a/test/fuzz-corpus/dhcp-server/request-renew b/test/fuzz/fuzz-dhcp-server/request-renew
index 8dcda2ad88..8dcda2ad88 100644
--- a/test/fuzz-corpus/dhcp-server/request-renew
+++ b/test/fuzz/fuzz-dhcp-server/request-renew
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae b/test/fuzz/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae
index 630ee6632c..630ee6632c 100644
--- a/test/fuzz-regressions/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae
+++ b/test/fuzz/fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef b/test/fuzz/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef
index 44883be9f0..44883be9f0 100644
--- a/test/fuzz-regressions/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef
+++ b/test/fuzz/fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-dns-packet/issue-7888 b/test/fuzz/fuzz-dns-packet/issue-7888
index 19e7eedf51..19e7eedf51 100644
--- a/test/fuzz-regressions/fuzz-dns-packet/issue-7888
+++ b/test/fuzz/fuzz-dns-packet/issue-7888
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-dns-packet/oss-fuzz-5465 b/test/fuzz/fuzz-dns-packet/oss-fuzz-5465
index ccd8a4fd6b..ccd8a4fd6b 100644
--- a/test/fuzz-regressions/fuzz-dns-packet/oss-fuzz-5465
+++ b/test/fuzz/fuzz-dns-packet/oss-fuzz-5465
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76 b/test/fuzz/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76
index e6a7316805..e6a7316805 100644
--- a/test/fuzz-regressions/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76
+++ b/test/fuzz/fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45 b/test/fuzz/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45
index 535d49ea7a..535d49ea7a 100644
--- a/test/fuzz-regressions/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45
+++ b/test/fuzz/fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45
Binary files differ
diff --git a/test/fuzz-corpus/journal-remote/invalid-ts.txt b/test/fuzz/fuzz-journal-remote/invalid-ts.txt
index bc036fdcb0..bc036fdcb0 100644
--- a/test/fuzz-corpus/journal-remote/invalid-ts.txt
+++ b/test/fuzz/fuzz-journal-remote/invalid-ts.txt
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8659 b/test/fuzz/fuzz-journal-remote/oss-fuzz-8659
index acc6a0f5e1..acc6a0f5e1 100644
--- a/test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8659
+++ b/test/fuzz/fuzz-journal-remote/oss-fuzz-8659
diff --git a/test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8686 b/test/fuzz/fuzz-journal-remote/oss-fuzz-8686
index 7c73c8cd9b..7c73c8cd9b 100644
--- a/test/fuzz-regressions/fuzz-journal-remote/oss-fuzz-8686
+++ b/test/fuzz/fuzz-journal-remote/oss-fuzz-8686
diff --git a/test/fuzz-corpus/journal-remote/sample.txt b/test/fuzz/fuzz-journal-remote/sample.txt
index 891c0003ef..891c0003ef 100644
--- a/test/fuzz-corpus/journal-remote/sample.txt
+++ b/test/fuzz/fuzz-journal-remote/sample.txt
diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9795 b/test/fuzz/fuzz-journald-syslog/github-9795
index 0519ecba6e..0519ecba6e 100644
--- a/test/fuzz-regressions/fuzz-journald-syslog/github-9795
+++ b/test/fuzz/fuzz-journald-syslog/github-9795
diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9820 b/test/fuzz/fuzz-journald-syslog/github-9820
index 55e1bb5967..55e1bb5967 100644
--- a/test/fuzz-regressions/fuzz-journald-syslog/github-9820
+++ b/test/fuzz/fuzz-journald-syslog/github-9820
diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9827 b/test/fuzz/fuzz-journald-syslog/github-9827
index 6787e487a4..6787e487a4 100644
--- a/test/fuzz-regressions/fuzz-journald-syslog/github-9827
+++ b/test/fuzz/fuzz-journald-syslog/github-9827
diff --git a/test/fuzz-regressions/fuzz-journald-syslog/github-9829 b/test/fuzz/fuzz-journald-syslog/github-9829
index 22ded55aa2..22ded55aa2 100644
--- a/test/fuzz-regressions/fuzz-journald-syslog/github-9829
+++ b/test/fuzz/fuzz-journald-syslog/github-9829
diff --git a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1 b/test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1
index 410cf38c1e..410cf38c1e 100644
--- a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1
+++ b/test/fuzz/fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1
Binary files differ
diff --git a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b b/test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b
index 04e871fbcb..04e871fbcb 100644
--- a/test/fuzz-regressions/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b
+++ b/test/fuzz/fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b
Binary files differ
diff --git a/test/fuzz-corpus/unit-file/dev-mapper-fedora_krowka\x2dswap.swap b/test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\x2dswap.swap
index 2886021b1a..2886021b1a 100644
--- a/test/fuzz-corpus/unit-file/dev-mapper-fedora_krowka\x2dswap.swap
+++ b/test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\x2dswap.swap
diff --git a/test/fuzz-corpus/unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
index b9c1b467b0..b9c1b467b0 100644
--- a/test/fuzz-corpus/unit-file/directives.service
+++ b/test/fuzz/fuzz-unit-file/directives.service
diff --git a/test/fuzz-corpus/unit-file/empty.scope b/test/fuzz/fuzz-unit-file/empty.scope
index 8df7245f62..8df7245f62 100644
--- a/test/fuzz-corpus/unit-file/empty.scope
+++ b/test/fuzz/fuzz-unit-file/empty.scope
diff --git a/test/fuzz-corpus/unit-file/machine.slice b/test/fuzz/fuzz-unit-file/machine.slice
index bf8c6bfc3e..bf8c6bfc3e 100644
--- a/test/fuzz-corpus/unit-file/machine.slice
+++ b/test/fuzz/fuzz-unit-file/machine.slice
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007 b/test/fuzz/fuzz-unit-file/oss-fuzz-10007
index 893630c83f..893630c83f 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-10007
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-10007
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6884 b/test/fuzz/fuzz-unit-file/oss-fuzz-6884
index 00d105ade5..00d105ade5 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6884
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6884
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6885 b/test/fuzz/fuzz-unit-file/oss-fuzz-6885
index 1859136fdc..1859136fdc 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6885
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6885
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6886 b/test/fuzz/fuzz-unit-file/oss-fuzz-6886
index 1fbe5ffd99..1fbe5ffd99 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6886
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6886
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6892 b/test/fuzz/fuzz-unit-file/oss-fuzz-6892
index 31f746d034..31f746d034 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6892
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6892
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897 b/test/fuzz/fuzz-unit-file/oss-fuzz-6897
index 742fd9bfeb..742fd9bfeb 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6897
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897-evverx b/test/fuzz/fuzz-unit-file/oss-fuzz-6897-evverx
index 126678e76c..126678e76c 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6897-evverx
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6897-evverx
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6908 b/test/fuzz/fuzz-unit-file/oss-fuzz-6908
index 8f2404b136..8f2404b136 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6908
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6908
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6917 b/test/fuzz/fuzz-unit-file/oss-fuzz-6917
index 9a79cf00b7..9a79cf00b7 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6917
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6917
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977 b/test/fuzz/fuzz-unit-file/oss-fuzz-6977
index 3d844e6f08..3d844e6f08 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6977
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-unminimized b/test/fuzz/fuzz-unit-file/oss-fuzz-6977-unminimized
index 718f94f0d7..718f94f0d7 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-6977-unminimized
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-6977-unminimized
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-7004 b/test/fuzz/fuzz-unit-file/oss-fuzz-7004
index 77a5e5e8d6..77a5e5e8d6 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-7004
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-7004
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064 b/test/fuzz/fuzz-unit-file/oss-fuzz-8064
index 2c6c1eaee7..2c6c1eaee7 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8064
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-8064
diff --git a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8827 b/test/fuzz/fuzz-unit-file/oss-fuzz-8827
index c71b75e134..c71b75e134 100644
--- a/test/fuzz-regressions/fuzz-unit-file/oss-fuzz-8827
+++ b/test/fuzz/fuzz-unit-file/oss-fuzz-8827
diff --git a/test/fuzz-corpus/unit-file/proc-sys-fs-binfmt_misc.automount b/test/fuzz/fuzz-unit-file/proc-sys-fs-binfmt_misc.automount
index 777a123ef4..777a123ef4 100644
--- a/test/fuzz-corpus/unit-file/proc-sys-fs-binfmt_misc.automount
+++ b/test/fuzz/fuzz-unit-file/proc-sys-fs-binfmt_misc.automount
diff --git a/test/fuzz-corpus/unit-file/syslog.socket b/test/fuzz/fuzz-unit-file/syslog.socket
index 2eb316fcaa..2eb316fcaa 100644
--- a/test/fuzz-corpus/unit-file/syslog.socket
+++ b/test/fuzz/fuzz-unit-file/syslog.socket
diff --git a/test/fuzz-corpus/unit-file/systemd-ask-password-console.path b/test/fuzz/fuzz-unit-file/systemd-ask-password-console.path
index 3e12c752de..3e12c752de 100644
--- a/test/fuzz-corpus/unit-file/systemd-ask-password-console.path
+++ b/test/fuzz/fuzz-unit-file/systemd-ask-password-console.path
diff --git a/test/fuzz-corpus/unit-file/systemd-machined.service b/test/fuzz/fuzz-unit-file/systemd-machined.service
index 448f062ecf..448f062ecf 100644
--- a/test/fuzz-corpus/unit-file/systemd-machined.service
+++ b/test/fuzz/fuzz-unit-file/systemd-machined.service
diff --git a/test/fuzz-corpus/unit-file/systemd-resolved.service b/test/fuzz/fuzz-unit-file/systemd-resolved.service
index 0854c5f841..0854c5f841 100644
--- a/test/fuzz-corpus/unit-file/systemd-resolved.service
+++ b/test/fuzz/fuzz-unit-file/systemd-resolved.service
diff --git a/test/fuzz-corpus/unit-file/systemd-tmpfiles-clean.timer b/test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer
index 7db361cd69..7db361cd69 100644
--- a/test/fuzz-corpus/unit-file/systemd-tmpfiles-clean.timer
+++ b/test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer
diff --git a/test/fuzz-corpus/unit-file/timers.target b/test/fuzz/fuzz-unit-file/timers.target
index 171226c680..171226c680 100644
--- a/test/fuzz-corpus/unit-file/timers.target
+++ b/test/fuzz/fuzz-unit-file/timers.target
diff --git a/test/fuzz-corpus/unit-file/var-lib-machines.mount b/test/fuzz/fuzz-unit-file/var-lib-machines.mount
index 9c257d1191..9c257d1191 100644
--- a/test/fuzz-corpus/unit-file/var-lib-machines.mount
+++ b/test/fuzz/fuzz-unit-file/var-lib-machines.mount
diff --git a/test/fuzz/meson.build b/test/fuzz/meson.build
new file mode 100644
index 0000000000..56d0f69660
--- /dev/null
+++ b/test/fuzz/meson.build
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: LGPL-2.1+
+
+sanitize_address = custom_target(
+ 'sanitize-address-fuzzers',
+ output : 'sanitize-address-fuzzers',
+ command : [meson_build_sh,
+ meson.source_root(),
+ '@OUTPUT@',
+ 'fuzzers',
+ '-Db_lundef=false -Db_sanitize=address'])
+
+sanitizers = [['address', sanitize_address]]
+
+if git.found()
+ out = run_command(
+ git,
+ '--git-dir=@0@/.git'.format(meson.source_root()),
+ 'ls-files', ':/test/fuzz/*/*')
+else
+ out = run_command(
+ 'sh', '-c', 'ls @0@/*/*'.format(meson.current_source_dir()))
+endif
+
+fuzz_regression_tests = []
+foreach p : out.stdout().split()
+ # Remove the last entry which is ''.
+ #
+ # Also, backslashes get mangled, so skip test. See
+ # https://github.com/mesonbuild/meson/issues/1564.
+ if not p.contains('\\')
+ fuzz_regression_tests += p
+ endif
+endforeach
diff --git a/test/meson.build b/test/meson.build
index 9750ff22b9..37034fca96 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -256,4 +256,4 @@ if conf.get('ENABLE_HWDB') == 1
endif
endif
-subdir('fuzz-regressions')
+subdir('fuzz')
diff --git a/tools/oss-fuzz.sh b/tools/oss-fuzz.sh
index 2db5b4cc44..4d11e81ed6 100755
--- a/tools/oss-fuzz.sh
+++ b/tools/oss-fuzz.sh
@@ -35,8 +35,10 @@ fi
meson $build -D$fuzzflag -Db_lundef=false
ninja -C $build fuzzers
-for d in "$(dirname "$0")/../test/fuzz-corpus/"*; do
- zip -jqr $OUT/fuzz-$(basename "$d")_seed_corpus.zip "$d"
+# The seed corpus is a separate flat archive for each fuzzer,
+# with a fixed name ${fuzzer}_seed_corpus.zip.
+for d in "$(dirname "$0")/../test/fuzz/fuzz-"*; do
+ zip -jqr $OUT/$(basename "$d")_seed_corpus.zip "$d"
done
# get fuzz-dns-packet corpus