fuzzers: move several fuzzers
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 31 Dec 2020 22:28:58 +0000 (07:28 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 18 Jan 2021 22:04:19 +0000 (07:04 +0900)
61 files changed:
src/core/fuzz-unit-file.c [new file with mode: 0644]
src/core/fuzz-unit-file.options [new file with mode: 0644]
src/fuzz/fuzz-dhcp-server.c [deleted file]
src/fuzz/fuzz-dhcp-server.options [deleted file]
src/fuzz/fuzz-dhcp6-client.c [deleted file]
src/fuzz/fuzz-dhcp6-client.options [deleted file]
src/fuzz/fuzz-dns-packet.c [deleted file]
src/fuzz/fuzz-dns-packet.options [deleted file]
src/fuzz/fuzz-journal-remote.c [deleted file]
src/fuzz/fuzz-journal-remote.options [deleted file]
src/fuzz/fuzz-journald-audit.c [deleted file]
src/fuzz/fuzz-journald-kmsg.c [deleted file]
src/fuzz/fuzz-journald-native-fd.c [deleted file]
src/fuzz/fuzz-journald-native.c [deleted file]
src/fuzz/fuzz-journald-stream.c [deleted file]
src/fuzz/fuzz-journald-stream.options [deleted file]
src/fuzz/fuzz-journald-syslog.c [deleted file]
src/fuzz/fuzz-journald.c [deleted file]
src/fuzz/fuzz-journald.h [deleted file]
src/fuzz/fuzz-lldp.c [deleted file]
src/fuzz/fuzz-lldp.options [deleted file]
src/fuzz/fuzz-ndisc-rs.c [deleted file]
src/fuzz/fuzz-ndisc-rs.options [deleted file]
src/fuzz/fuzz-nspawn-oci.c [deleted file]
src/fuzz/fuzz-nspawn-oci.options [deleted file]
src/fuzz/fuzz-nspawn-settings.c [deleted file]
src/fuzz/fuzz-nspawn-settings.options [deleted file]
src/fuzz/fuzz-udev-rule-parse-value.c [deleted file]
src/fuzz/fuzz-udev-rules.c [deleted file]
src/fuzz/fuzz-udev-rules.options [deleted file]
src/fuzz/fuzz-unit-file.c [deleted file]
src/fuzz/fuzz-unit-file.options [deleted file]
src/fuzz/meson.build
src/journal-remote/fuzz-journal-remote.c [new file with mode: 0644]
src/journal-remote/fuzz-journal-remote.options [new file with mode: 0644]
src/journal/fuzz-journald-audit.c [new file with mode: 0644]
src/journal/fuzz-journald-kmsg.c [new file with mode: 0644]
src/journal/fuzz-journald-native-fd.c [new file with mode: 0644]
src/journal/fuzz-journald-native.c [new file with mode: 0644]
src/journal/fuzz-journald-stream.c [new file with mode: 0644]
src/journal/fuzz-journald-stream.options [new file with mode: 0644]
src/journal/fuzz-journald-syslog.c [new file with mode: 0644]
src/journal/fuzz-journald.c [new file with mode: 0644]
src/journal/fuzz-journald.h [new file with mode: 0644]
src/libsystemd-network/fuzz-dhcp-server.c [new file with mode: 0644]
src/libsystemd-network/fuzz-dhcp-server.options [new file with mode: 0644]
src/libsystemd-network/fuzz-dhcp6-client.c [new file with mode: 0644]
src/libsystemd-network/fuzz-dhcp6-client.options [new file with mode: 0644]
src/libsystemd-network/fuzz-lldp.c [new file with mode: 0644]
src/libsystemd-network/fuzz-lldp.options [new file with mode: 0644]
src/libsystemd-network/fuzz-ndisc-rs.c [new file with mode: 0644]
src/libsystemd-network/fuzz-ndisc-rs.options [new file with mode: 0644]
src/nspawn/fuzz-nspawn-oci.c [new file with mode: 0644]
src/nspawn/fuzz-nspawn-oci.options [new file with mode: 0644]
src/nspawn/fuzz-nspawn-settings.c [new file with mode: 0644]
src/nspawn/fuzz-nspawn-settings.options [new file with mode: 0644]
src/resolve/fuzz-dns-packet.c [new file with mode: 0644]
src/resolve/fuzz-dns-packet.options [new file with mode: 0644]
src/udev/fuzz-udev-rule-parse-value.c [new file with mode: 0644]
src/udev/fuzz-udev-rules.c [new file with mode: 0644]
src/udev/fuzz-udev-rules.options [new file with mode: 0644]

diff --git a/src/core/fuzz-unit-file.c b/src/core/fuzz-unit-file.c
new file mode 100644 (file)
index 0000000..e67f6e9
--- /dev/null
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "conf-parser.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fuzz.h"
+#include "install.h"
+#include "load-fragment.h"
+#include "string-util.h"
+#include "unit.h"
+#include "utf8.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 *f = NULL, *g = NULL;
+        _cleanup_free_ char *p = NULL;
+        UnitType t;
+        _cleanup_(manager_freep) Manager *m = NULL;
+        Unit *u;
+        const char *name;
+        long offset;
+
+        if (size == 0)
+                return 0;
+
+        f = fmemopen_unlocked((char*) data, size, "re");
+        assert_se(f);
+
+        if (read_line(f, LINE_MAX, &p) < 0)
+                return 0;
+
+        t = unit_type_from_string(p);
+        if (t < 0)
+                return 0;
+
+        if (!unit_vtable[t]->load)
+                return 0;
+
+        offset = ftell(f);
+        assert_se(offset >= 0);
+
+        for (;;) {
+                _cleanup_free_ char *l = NULL;
+                const char *ll;
+
+                if (read_line(f, LONG_LINE_MAX, &l) <= 0)
+                        break;
+
+                ll = startswith(l, UTF8_BYTE_ORDER_MARK) ?: l;
+                ll = ll + strspn(ll, WHITESPACE);
+
+                if (HAS_FEATURE_MEMORY_SANITIZER && startswith(ll, "ListenNetlink")) {
+                        /* ListenNetlink causes a false positive in msan,
+                         * let's skip this for now. */
+                        log_notice("Skipping test because ListenNetlink= is present");
+                        return 0;
+                }
+        }
+
+        assert_se(fseek(f, offset, SEEK_SET) == 0);
+
+        /* 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);
+
+        assert_se(manager_new(UNIT_FILE_SYSTEM, MANAGER_TEST_RUN_MINIMAL, &m) >= 0);
+
+        name = strjoina("a.", unit_type_to_string(t));
+        assert_se(unit_new_for_name(m, unit_vtable[t]->object_size, name, &u) >= 0);
+
+        (void) config_parse(
+                        name, name, f,
+                        UNIT_VTABLE(u)->sections,
+                        config_item_perf_lookup, load_fragment_gperf_lookup,
+                        0,
+                        u,
+                        NULL);
+
+        g = open_memstream_unlocked(&out, &out_size);
+        assert_se(g);
+
+        unit_dump(u, g, "");
+        manager_dump(m, g, ">>>");
+
+        return 0;
+}
diff --git a/src/core/fuzz-unit-file.options b/src/core/fuzz-unit-file.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
diff --git a/src/fuzz/fuzz-dhcp-server.c b/src/fuzz/fuzz-dhcp-server.c
deleted file mode 100644 (file)
index c854d92..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "fuzz.h"
-
-#include "sd-dhcp-server.c"
-
-/* stub out network so that the server doesn't send */
-ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) {
-        return len;
-}
-
-ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) {
-        return 0;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;
-        struct in_addr address = {.s_addr = htobe32(UINT32_C(10) << 24 | UINT32_C(1))};
-        static const uint8_t chaddr[] = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
-        uint8_t *client_id;
-        DHCPLease *lease;
-        int pool_offset;
-
-        if (size < sizeof(DHCPMessage))
-                return 0;
-
-        assert_se(sd_dhcp_server_new(&server, 1) >= 0);
-        server->fd = open("/dev/null", O_RDWR|O_CLOEXEC|O_NOCTTY);
-        assert_se(server->fd >= 0);
-        assert_se(sd_dhcp_server_configure_pool(server, &address, 24, 0, 0) >= 0);
-
-        /* add a lease to the pool to expose additional code paths */
-        client_id = malloc(2);
-        assert_se(client_id);
-        client_id[0] = 2;
-        client_id[1] = 2;
-        lease = new0(DHCPLease, 1);
-        assert_se(lease);
-        lease->client_id.length = 2;
-        lease->client_id.data = client_id;
-        lease->address = htobe32(UINT32_C(10) << 24 | UINT32_C(2));
-        lease->gateway = htobe32(UINT32_C(10) << 24 | UINT32_C(1));
-        lease->expiration = UINT64_MAX;
-        memcpy(lease->chaddr, chaddr, 16);
-        pool_offset = get_pool_offset(server, lease->address);
-        server->bound_leases[pool_offset] = lease;
-        assert_se(hashmap_put(server->leases_by_client_id, &lease->client_id, lease) >= 0);
-
-        (void) dhcp_server_handle_message(server, (DHCPMessage*)data, size);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-dhcp-server.options b/src/fuzz/fuzz-dhcp-server.options
deleted file mode 100644 (file)
index 5c330e5..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 600
diff --git a/src/fuzz/fuzz-dhcp6-client.c b/src/fuzz/fuzz-dhcp6-client.c
deleted file mode 100644 (file)
index e5e70dd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <unistd.h>
-
-#include "sd-dhcp6-client.h"
-#include "sd-event.h"
-
-#include "dhcp6-internal.h"
-#include "dhcp6-protocol.h"
-#include "fd-util.h"
-#include "fuzz.h"
-
-static int test_dhcp_fd[2] = { -1, -1 };
-
-int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
-                                  const void *packet, size_t len) {
-        return len;
-}
-
-int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
-        assert_se(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_dhcp_fd) >= 0);
-        return test_dhcp_fd[0];
-}
-
-static void fuzz_client(const uint8_t *data, size_t size, bool is_information_request_enabled) {
-        _cleanup_(sd_event_unrefp) sd_event *e;
-        _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
-        struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
-
-        assert_se(sd_event_new(&e) >= 0);
-        assert_se(sd_dhcp6_client_new(&client) >= 0);
-        assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
-        assert_se(sd_dhcp6_client_set_ifindex(client, 42) == 0);
-        assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
-        assert_se(sd_dhcp6_client_set_information_request(client, is_information_request_enabled) == 0);
-
-        assert_se(sd_dhcp6_client_start(client) >= 0);
-
-        if (size >= sizeof(DHCP6Message))
-                assert_se(sd_dhcp6_client_set_transaction_id(client, htobe32(0x00ffffff) & ((const DHCP6Message *) data)->transaction_id) == 0);
-
-        assert_se(write(test_dhcp_fd[1], data, size) == (ssize_t) size);
-
-        sd_event_run(e, (uint64_t) -1);
-
-        assert_se(sd_dhcp6_client_stop(client) >= 0);
-
-        test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        if (size > 65536)
-                return 0;
-
-        /* This triggers client_receive_advertise */
-        fuzz_client(data, size, false);
-
-        /* This triggers client_receive_reply */
-        fuzz_client(data, size, true);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-dhcp6-client.options b/src/fuzz/fuzz-dhcp6-client.options
deleted file mode 100644 (file)
index 678d526..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65536
diff --git a/src/fuzz/fuzz-dns-packet.c b/src/fuzz/fuzz-dns-packet.c
deleted file mode 100644 (file)
index b9a0aa1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "fuzz.h"
-#include "memory-util.h"
-#include "resolved-dns-packet.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
-
-        if (size > DNS_PACKET_SIZE_MAX)
-                return 0;
-
-        assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, 0, DNS_PACKET_SIZE_MAX) >= 0);
-        p->size = 0; /* by default append starts after the header, undo that */
-        assert_se(dns_packet_append_blob(p, data, size, NULL) >= 0);
-        if (size < DNS_PACKET_HEADER_SIZE) {
-                /* make sure we pad the packet back up to the minimum header size */
-                assert_se(p->allocated >= DNS_PACKET_HEADER_SIZE);
-                memzero(DNS_PACKET_DATA(p) + size, DNS_PACKET_HEADER_SIZE - size);
-                p->size = DNS_PACKET_HEADER_SIZE;
-        }
-        (void) dns_packet_extract(p);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-dns-packet.options b/src/fuzz/fuzz-dns-packet.options
deleted file mode 100644 (file)
index 0824b19..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65535
diff --git a/src/fuzz/fuzz-journal-remote.c b/src/fuzz/fuzz-journal-remote.c
deleted file mode 100644 (file)
index 9adbd43..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "fuzz.h"
-
-#include <sys/mman.h>
-
-#include "sd-journal.h"
-
-#include "env-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fs-util.h"
-#include "journal-remote.h"
-#include "logs-show.h"
-#include "memfd-util.h"
-#include "strv.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_fclose_ FILE *dev_null = NULL;
-        RemoteServer s = {};
-        char name[] = "/tmp/fuzz-journal-remote.XXXXXX.journal";
-        void *mem;
-        int fdin; /* will be closed by journal_remote handler after EOF */
-        _cleanup_close_ int fdout = -1;
-        sd_journal *j;
-        OutputMode mode;
-        int r;
-
-        if (size <= 2)
-                return 0;
-
-        if (!getenv("SYSTEMD_LOG_LEVEL"))
-                log_set_max_level(LOG_CRIT);
-
-        assert_se((fdin = memfd_new_and_map("fuzz-journal-remote", size, &mem)) >= 0);
-        memcpy(mem, data, size);
-        assert_se(munmap(mem, size) == 0);
-
-        fdout = mkostemps(name, STRLEN(".journal"), O_CLOEXEC);
-        assert_se(fdout >= 0);
-
-        /* In */
-
-        assert_se(journal_remote_server_init(&s, name, JOURNAL_WRITE_SPLIT_NONE, false, false) >= 0);
-
-        assert_se(journal_remote_add_source(&s, fdin, (char*) "fuzz-data", false) > 0);
-
-        while (s.active) {
-                r = journal_remote_handle_raw_source(NULL, fdin, 0, &s);
-                assert_se(r >= 0);
-        }
-
-        journal_remote_server_destroy(&s);
-        assert_se(close(fdin) < 0 && errno == EBADF); /* Check that the fd is closed already */
-
-        /* Out */
-
-        r = sd_journal_open_files(&j, (const char**) STRV_MAKE(name), 0);
-        assert_se(r >= 0);
-
-        if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0)
-                assert_se(dev_null = fopen("/dev/null", "we"));
-
-        for (mode = 0; mode < _OUTPUT_MODE_MAX; mode++) {
-                if (!dev_null)
-                        log_info("/* %s */", output_mode_to_string(mode));
-                r = show_journal(dev_null ?: stdout, j, mode, 0, 0, -1, 0, NULL);
-                assert_se(r >= 0);
-
-                r = sd_journal_seek_head(j);
-                assert_se(r >= 0);
-        }
-
-        sd_journal_close(j);
-        unlink(name);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-journal-remote.options b/src/fuzz/fuzz-journal-remote.options
deleted file mode 100644 (file)
index 678d526..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65536
diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c
deleted file mode 100644 (file)
index 6e8e180..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "fuzz.h"
-#include "fuzz-journald.h"
-#include "journald-audit.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        Server s;
-
-        dummy_server_init(&s, data, size);
-        process_audit_string(&s, 0, s.buffer, size);
-        server_done(&s);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c
deleted file mode 100644 (file)
index 1b423d5..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "fuzz.h"
-#include "fuzz-journald.h"
-#include "journald-kmsg.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        Server s;
-
-        if (size == 0)
-                return 0;
-
-        dummy_server_init(&s, data, size);
-        dev_kmsg_record(&s, s.buffer, size);
-        server_done(&s);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-journald-native-fd.c b/src/fuzz/fuzz-journald-native-fd.c
deleted file mode 100644 (file)
index fcfc5df..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "fd-util.h"
-#include "fs-util.h"
-#include "fuzz-journald.h"
-#include "fuzz.h"
-#include "journald-native.h"
-#include "memfd-util.h"
-#include "process-util.h"
-#include "tmpfile-util.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        Server s;
-        _cleanup_close_ int sealed_fd = -1, unsealed_fd = -1;
-        _cleanup_(unlink_tempfilep) char name[] = "/tmp/fuzz-journald-native-fd.XXXXXX";
-        char *label = NULL;
-        size_t label_len = 0;
-        struct ucred ucred;
-        struct timeval *tv = NULL;
-
-        if (!getenv("SYSTEMD_LOG_LEVEL"))
-                log_set_max_level(LOG_CRIT);
-
-        dummy_server_init(&s, NULL, 0);
-
-        sealed_fd = memfd_new(NULL);
-        assert_se(sealed_fd >= 0);
-        assert_se(write(sealed_fd, data, size) == (ssize_t) size);
-        assert_se(memfd_set_sealed(sealed_fd) >= 0);
-        assert_se(lseek(sealed_fd, 0, SEEK_SET) == 0);
-        ucred = (struct ucred) {
-                .pid = getpid_cached(),
-                .uid = geteuid(),
-                .gid = getegid(),
-        };
-        server_process_native_file(&s, sealed_fd, &ucred, tv, label, label_len);
-
-        unsealed_fd = mkostemp_safe(name);
-        assert_se(unsealed_fd >= 0);
-        assert_se(write(unsealed_fd, data, size) == (ssize_t) size);
-        assert_se(lseek(unsealed_fd, 0, SEEK_SET) == 0);
-        server_process_native_file(&s, unsealed_fd, &ucred, tv, label, label_len);
-
-        server_done(&s);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-journald-native.c b/src/fuzz/fuzz-journald-native.c
deleted file mode 100644 (file)
index 6531c4f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "fuzz.h"
-#include "fuzz-journald.h"
-#include "journald-native.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        fuzz_journald_processing_function(data, size, server_process_native_message);
-        return 0;
-}
diff --git a/src/fuzz/fuzz-journald-stream.c b/src/fuzz/fuzz-journald-stream.c
deleted file mode 100644 (file)
index 038b335..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <linux/sockios.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-#include "fd-util.h"
-#include "fuzz.h"
-#include "fuzz-journald.h"
-#include "journald-stream.h"
-
-static int stream_fds[2] = { -1, -1 };
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        Server s;
-        StdoutStream *stream;
-        int v;
-
-        if (size == 0 || size > 65536)
-                return 0;
-
-        if (!getenv("SYSTEMD_LOG_LEVEL"))
-                log_set_max_level(LOG_CRIT);
-
-        assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, stream_fds) >= 0);
-        dummy_server_init(&s, NULL, 0);
-        assert_se(stdout_stream_install(&s, stream_fds[0], &stream) >= 0);
-        assert_se(write(stream_fds[1], data, size) == (ssize_t) size);
-        while (ioctl(stream_fds[0], SIOCINQ, &v) == 0 && v)
-                sd_event_run(s.event, (uint64_t) -1);
-        if (s.n_stdout_streams)
-                stdout_stream_destroy(stream);
-        server_done(&s);
-        stream_fds[1] = safe_close(stream_fds[1]);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-journald-stream.options b/src/fuzz/fuzz-journald-stream.options
deleted file mode 100644 (file)
index 678d526..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65536
diff --git a/src/fuzz/fuzz-journald-syslog.c b/src/fuzz/fuzz-journald-syslog.c
deleted file mode 100644 (file)
index 72ec610..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "fuzz.h"
-#include "fuzz-journald.h"
-#include "journald-syslog.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        fuzz_journald_processing_function(data, size, server_process_syslog_message);
-        return 0;
-}
diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c
deleted file mode 100644 (file)
index e2f73ff..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "alloc-util.h"
-#include "fuzz-journald.h"
-#include "journald-server.h"
-#include "sd-event.h"
-
-void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
-        *s = (Server) {
-                .syslog_fd = -1,
-                .native_fd = -1,
-                .stdout_fd = -1,
-                .dev_kmsg_fd = -1,
-                .audit_fd = -1,
-                .hostname_fd = -1,
-                .notify_fd = -1,
-                .storage = STORAGE_NONE,
-                .line_max = 64,
-        };
-        assert_se(sd_event_default(&s->event) >= 0);
-
-        if (buffer) {
-                s->buffer = memdup_suffix0(buffer, size);
-                assert_se(s->buffer);
-                s->buffer_size = size + 1;
-        }
-}
-
-void fuzz_journald_processing_function(
-                const uint8_t *data,
-                size_t size,
-                void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
-        ) {
-        Server s;
-        char *label = NULL;
-        size_t label_len = 0;
-        struct ucred *ucred = NULL;
-        struct timeval *tv = NULL;
-
-        if (size == 0)
-                return;
-
-        dummy_server_init(&s, data, size);
-        (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
-        server_done(&s);
-}
diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h
deleted file mode 100644 (file)
index 4abb100..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include "journald-server.h"
-
-void dummy_server_init(Server *s, const uint8_t *buffer, size_t size);
-
-void fuzz_journald_processing_function(
-                const uint8_t *data,
-                size_t size,
-                void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
-);
diff --git a/src/fuzz/fuzz-lldp.c b/src/fuzz/fuzz-lldp.c
deleted file mode 100644 (file)
index 5747135..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <errno.h>
-#include <unistd.h>
-
-#include "sd-event.h"
-#include "sd-lldp.h"
-
-#include "fd-util.h"
-#include "fuzz.h"
-#include "lldp-network.h"
-
-static int test_fd[2] = { -1, -1 };
-
-int lldp_network_bind_raw_socket(int ifindex) {
-        if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
-                return -errno;
-
-        return test_fd[0];
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
-        _cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL;
-
-        if (size > 2048)
-                return 0;
-
-        assert_se(sd_event_new(&e) == 0);
-        assert_se(sd_lldp_new(&lldp) >= 0);
-        assert_se(sd_lldp_set_ifindex(lldp, 42) >= 0);
-        assert_se(sd_lldp_attach_event(lldp, e, 0) >= 0);
-        assert_se(sd_lldp_start(lldp) >= 0);
-
-        assert_se(write(test_fd[1], data, size) == (ssize_t) size);
-        assert_se(sd_event_run(e, 0) >= 0);
-
-        assert_se(sd_lldp_stop(lldp) >= 0);
-        assert_se(sd_lldp_detach_event(lldp) >= 0);
-        test_fd[1] = safe_close(test_fd[1]);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-lldp.options b/src/fuzz/fuzz-lldp.options
deleted file mode 100644 (file)
index 60bd9b0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 2048
diff --git a/src/fuzz/fuzz-ndisc-rs.c b/src/fuzz/fuzz-ndisc-rs.c
deleted file mode 100644 (file)
index d74cd2f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <arpa/inet.h>
-#include <netinet/icmp6.h>
-#include <unistd.h>
-
-#include "alloc-util.h"
-#include "icmp6-util.h"
-#include "fuzz.h"
-#include "sd-ndisc.h"
-#include "socket-util.h"
-#include "ndisc-internal.h"
-
-static int test_fd[2] = { -1, -1 };
-
-int icmp6_bind_router_solicitation(int index) {
-        assert_se(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
-        return test_fd[0];
-}
-
-int icmp6_bind_router_advertisement(int index) {
-        return -ENOSYS;
-}
-
-int icmp6_receive(int fd, void *iov_base, size_t iov_len,
-                  struct in6_addr *dst, triple_timestamp *timestamp) {
-        assert_se(read(fd, iov_base, iov_len) == (ssize_t) iov_len);
-
-        if (timestamp)
-                triple_timestamp_get(timestamp);
-
-        return 0;
-}
-
-int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
-        return 0;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        struct ether_addr mac_addr = {
-                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
-        };
-        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
-        _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL;
-
-        if (size > 2048)
-                return 0;
-
-        assert_se(sd_event_new(&e) >= 0);
-        assert_se(sd_ndisc_new(&nd) >= 0);
-        assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0);
-        assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0);
-        assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0);
-        assert_se(sd_ndisc_start(nd) >= 0);
-        assert_se(write(test_fd[1], data, size) == (ssize_t) size);
-        (void) sd_event_run(e, (uint64_t) -1);
-        assert_se(sd_ndisc_stop(nd) >= 0);
-        close(test_fd[1]);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-ndisc-rs.options b/src/fuzz/fuzz-ndisc-rs.options
deleted file mode 100644 (file)
index 60bd9b0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 2048
diff --git a/src/fuzz/fuzz-nspawn-oci.c b/src/fuzz/fuzz-nspawn-oci.c
deleted file mode 100644 (file)
index cfebf65..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fuzz.h"
-#include "nspawn-oci.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_(settings_freep) Settings *s = NULL;
-
-        if (size == 0)
-                return 0;
-
-        f = fmemopen_unlocked((char*) data, size, "re");
-        assert_se(f);
-
-        /* 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);
-
-        (void) oci_load(f, "/dev/null", &s);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-nspawn-oci.options b/src/fuzz/fuzz-nspawn-oci.options
deleted file mode 100644 (file)
index 678d526..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65536
diff --git a/src/fuzz/fuzz-nspawn-settings.c b/src/fuzz/fuzz-nspawn-settings.c
deleted file mode 100644 (file)
index bd98ed2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "alloc-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fuzz.h"
-#include "nspawn-settings.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_(settings_freep) Settings *s = NULL;
-
-        if (size == 0)
-                return 0;
-
-        f = fmemopen_unlocked((char*) data, size, "re");
-        assert_se(f);
-
-        /* 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);
-
-        (void) settings_load(f, "/dev/null", &s);
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-nspawn-settings.options b/src/fuzz/fuzz-nspawn-settings.options
deleted file mode 100644 (file)
index 678d526..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65536
diff --git a/src/fuzz/fuzz-udev-rule-parse-value.c b/src/fuzz/fuzz-udev-rule-parse-value.c
deleted file mode 100644 (file)
index 404d0cd..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <string.h>
-
-#include "alloc-util.h"
-#include "fuzz.h"
-#include "udev-util.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_free_ char *str = NULL;
-        int r;
-        char *value = UINT_TO_PTR(0x12345678U);
-        char *endpos = UINT_TO_PTR(0x87654321U);
-
-        assert_se(str = malloc(size + 1));
-        memcpy(str, data, size);
-        str[size] = '\0';
-
-        r = udev_rule_parse_value(str, &value, &endpos);
-
-        if (r < 0) {
-                /* not modified on failure */
-                assert_se(value == UINT_TO_PTR(0x12345678U));
-                assert_se(endpos == UINT_TO_PTR(0x87654321U));
-        } else {
-                assert_se(endpos <= str + size);
-                assert_se(endpos > str + 1);
-        }
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-udev-rules.c b/src/fuzz/fuzz-udev-rules.c
deleted file mode 100644 (file)
index e1140bc..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <stdio.h>
-
-#include "fd-util.h"
-#include "fs-util.h"
-#include "fuzz.h"
-#include "tests.h"
-#include "tmpfile-util.h"
-#include "udev-rules.h"
-
-int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-        _cleanup_(udev_rules_freep) UdevRules *rules = NULL;
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_(unlink_tempfilep) char filename[] = "/tmp/fuzz-udev-rules.XXXXXX";
-        int r;
-
-        if (!getenv("SYSTEMD_LOG_LEVEL")) {
-                log_set_max_level_realm(LOG_REALM_UDEV, LOG_CRIT);
-                log_set_max_level_realm(LOG_REALM_SYSTEMD, LOG_CRIT);
-        }
-
-        assert_se(fmkostemp_safe(filename, "r+", &f) == 0);
-        if (size != 0)
-                assert_se(fwrite(data, size, 1, f) == 1);
-        fflush(f);
-
-        assert_se(rules = udev_rules_new(RESOLVE_NAME_EARLY));
-        r = udev_rules_parse_file(rules, filename);
-        log_info_errno(r, "Parsing %s: %m", filename);
-        assert_se(IN_SET(r,
-                         0,       /* OK */
-                         -ENOBUFS /* line length exceeded */));
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-udev-rules.options b/src/fuzz/fuzz-udev-rules.options
deleted file mode 100644 (file)
index 678d526..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65536
diff --git a/src/fuzz/fuzz-unit-file.c b/src/fuzz/fuzz-unit-file.c
deleted file mode 100644 (file)
index e67f6e9..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "conf-parser.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "fuzz.h"
-#include "install.h"
-#include "load-fragment.h"
-#include "string-util.h"
-#include "unit.h"
-#include "utf8.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 *f = NULL, *g = NULL;
-        _cleanup_free_ char *p = NULL;
-        UnitType t;
-        _cleanup_(manager_freep) Manager *m = NULL;
-        Unit *u;
-        const char *name;
-        long offset;
-
-        if (size == 0)
-                return 0;
-
-        f = fmemopen_unlocked((char*) data, size, "re");
-        assert_se(f);
-
-        if (read_line(f, LINE_MAX, &p) < 0)
-                return 0;
-
-        t = unit_type_from_string(p);
-        if (t < 0)
-                return 0;
-
-        if (!unit_vtable[t]->load)
-                return 0;
-
-        offset = ftell(f);
-        assert_se(offset >= 0);
-
-        for (;;) {
-                _cleanup_free_ char *l = NULL;
-                const char *ll;
-
-                if (read_line(f, LONG_LINE_MAX, &l) <= 0)
-                        break;
-
-                ll = startswith(l, UTF8_BYTE_ORDER_MARK) ?: l;
-                ll = ll + strspn(ll, WHITESPACE);
-
-                if (HAS_FEATURE_MEMORY_SANITIZER && startswith(ll, "ListenNetlink")) {
-                        /* ListenNetlink causes a false positive in msan,
-                         * let's skip this for now. */
-                        log_notice("Skipping test because ListenNetlink= is present");
-                        return 0;
-                }
-        }
-
-        assert_se(fseek(f, offset, SEEK_SET) == 0);
-
-        /* 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);
-
-        assert_se(manager_new(UNIT_FILE_SYSTEM, MANAGER_TEST_RUN_MINIMAL, &m) >= 0);
-
-        name = strjoina("a.", unit_type_to_string(t));
-        assert_se(unit_new_for_name(m, unit_vtable[t]->object_size, name, &u) >= 0);
-
-        (void) config_parse(
-                        name, name, f,
-                        UNIT_VTABLE(u)->sections,
-                        config_item_perf_lookup, load_fragment_gperf_lookup,
-                        0,
-                        u,
-                        NULL);
-
-        g = open_memstream_unlocked(&out, &out_size);
-        assert_se(g);
-
-        unit_dump(u, g, "");
-        manager_dump(m, g, ">>>");
-
-        return 0;
-}
diff --git a/src/fuzz/fuzz-unit-file.options b/src/fuzz/fuzz-unit-file.options
deleted file mode 100644 (file)
index 678d526..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-max_len = 65536
index f4508b514012f359da884cb1ba2de9a8a9c19ea8..36bef1c7af80505840a831adfa553969a7761d85 100644 (file)
@@ -7,7 +7,7 @@ fuzzers += [
          [libjournal_core,
           libshared]],
 
-        [['src/fuzz/fuzz-dns-packet.c',
+        [['src/resolve/fuzz-dns-packet.c',
           dns_type_headers],
          [libsystemd_resolve_core,
           libshared],
@@ -15,28 +15,19 @@ fuzzers += [
           libgpg_error,
           libm]],
 
-        [['src/fuzz/fuzz-dhcp6-client.c',
-          'src/libsystemd-network/dhcp-identifier.h',
-          'src/libsystemd-network/dhcp-identifier.c',
-          'src/libsystemd-network/dhcp6-internal.h',
-          'src/systemd/sd-dhcp6-client.h'],
+        [['src/libsystemd-network/fuzz-dhcp6-client.c'],
          [libshared,
           libsystemd_network]],
 
-        [['src/fuzz/fuzz-dhcp-server.c'],
+        [['src/libsystemd-network/fuzz-dhcp-server.c'],
          [libsystemd_network,
           libshared]],
 
-        [['src/fuzz/fuzz-lldp.c'],
+        [['src/libsystemd-network/fuzz-lldp.c'],
          [libshared,
           libsystemd_network]],
 
-        [['src/fuzz/fuzz-ndisc-rs.c',
-          'src/libsystemd-network/dhcp-identifier.h',
-          'src/libsystemd-network/dhcp-identifier.c',
-          'src/libsystemd-network/icmp6-util.h',
-          'src/systemd/sd-dhcp6-client.h',
-          'src/systemd/sd-ndisc.h'],
+        [['src/libsystemd-network/fuzz-ndisc-rs.c'],
          [libshared,
           libsystemd_network]],
 
@@ -44,54 +35,54 @@ fuzzers += [
 
         [['src/fuzz/fuzz-varlink.c']],
 
-        [['src/fuzz/fuzz-unit-file.c'],
+        [['src/core/fuzz-unit-file.c'],
          [libcore,
           libshared],
          [libmount]],
 
-        [['src/fuzz/fuzz-journald-audit.c',
-          'src/fuzz/fuzz-journald.c'],
+        [['src/journal/fuzz-journald-audit.c',
+          'src/journal/fuzz-journald.c'],
          [libjournal_core,
           libshared],
          [libselinux]],
 
-        [['src/fuzz/fuzz-journald-kmsg.c',
-          'src/fuzz/fuzz-journald.c'],
+        [['src/journal/fuzz-journald-kmsg.c',
+          'src/journal/fuzz-journald.c'],
          [libjournal_core,
           libshared],
          [libselinux]],
 
-        [['src/fuzz/fuzz-journald-native.c',
-          'src/fuzz/fuzz-journald.c'],
+        [['src/journal/fuzz-journald-native.c',
+          'src/journal/fuzz-journald.c'],
          [libjournal_core,
           libshared],
          [libselinux]],
 
-        [['src/fuzz/fuzz-journald-native-fd.c',
-          'src/fuzz/fuzz-journald.c'],
+        [['src/journal/fuzz-journald-native-fd.c',
+          'src/journal/fuzz-journald.c'],
          [libjournal_core,
           libshared],
          [libselinux]],
 
-        [['src/fuzz/fuzz-journald-stream.c',
-          'src/fuzz/fuzz-journald.c'],
+        [['src/journal/fuzz-journald-stream.c',
+          'src/journal/fuzz-journald.c'],
          [libjournal_core,
           libshared],
          [libselinux]],
 
-        [['src/fuzz/fuzz-journald-syslog.c',
-          'src/fuzz/fuzz-journald.c'],
+        [['src/journal/fuzz-journald-syslog.c',
+          'src/journal/fuzz-journald.c'],
          [libjournal_core,
           libshared],
          [libselinux]],
 
-        [['src/fuzz/fuzz-journal-remote.c'],
+        [['src/journal-remote/fuzz-journal-remote.c'],
          [libsystemd_journal_remote,
           libshared]],
 
         [['src/fuzz/fuzz-udev-database.c']],
 
-        [['src/fuzz/fuzz-udev-rules.c'],
+        [['src/udev/fuzz-udev-rules.c'],
          [libudevd_core,
           libshared],
          [threads,
@@ -105,12 +96,12 @@ fuzzers += [
 
         [['src/fuzz/fuzz-hostname-setup.c']],
 
-        [['src/fuzz/fuzz-nspawn-settings.c'],
+        [['src/nspawn/fuzz-nspawn-settings.c'],
          [libshared,
           libnspawn_core],
          [libseccomp]],
 
-        [['src/fuzz/fuzz-nspawn-oci.c'],
+        [['src/nspawn/fuzz-nspawn-oci.c'],
          [libshared,
           libnspawn_core],
          [libseccomp]],
@@ -123,5 +114,5 @@ fuzzers += [
           'src/xdg-autostart-generator/xdg-autostart-service.h',
           'src/xdg-autostart-generator/xdg-autostart-service.c']],
 
-        [['src/fuzz/fuzz-udev-rule-parse-value.c']],
+        [['src/udev/fuzz-udev-rule-parse-value.c']],
 ]
diff --git a/src/journal-remote/fuzz-journal-remote.c b/src/journal-remote/fuzz-journal-remote.c
new file mode 100644 (file)
index 0000000..9adbd43
--- /dev/null
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fuzz.h"
+
+#include <sys/mman.h>
+
+#include "sd-journal.h"
+
+#include "env-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fs-util.h"
+#include "journal-remote.h"
+#include "logs-show.h"
+#include "memfd-util.h"
+#include "strv.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_fclose_ FILE *dev_null = NULL;
+        RemoteServer s = {};
+        char name[] = "/tmp/fuzz-journal-remote.XXXXXX.journal";
+        void *mem;
+        int fdin; /* will be closed by journal_remote handler after EOF */
+        _cleanup_close_ int fdout = -1;
+        sd_journal *j;
+        OutputMode mode;
+        int r;
+
+        if (size <= 2)
+                return 0;
+
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
+                log_set_max_level(LOG_CRIT);
+
+        assert_se((fdin = memfd_new_and_map("fuzz-journal-remote", size, &mem)) >= 0);
+        memcpy(mem, data, size);
+        assert_se(munmap(mem, size) == 0);
+
+        fdout = mkostemps(name, STRLEN(".journal"), O_CLOEXEC);
+        assert_se(fdout >= 0);
+
+        /* In */
+
+        assert_se(journal_remote_server_init(&s, name, JOURNAL_WRITE_SPLIT_NONE, false, false) >= 0);
+
+        assert_se(journal_remote_add_source(&s, fdin, (char*) "fuzz-data", false) > 0);
+
+        while (s.active) {
+                r = journal_remote_handle_raw_source(NULL, fdin, 0, &s);
+                assert_se(r >= 0);
+        }
+
+        journal_remote_server_destroy(&s);
+        assert_se(close(fdin) < 0 && errno == EBADF); /* Check that the fd is closed already */
+
+        /* Out */
+
+        r = sd_journal_open_files(&j, (const char**) STRV_MAKE(name), 0);
+        assert_se(r >= 0);
+
+        if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0)
+                assert_se(dev_null = fopen("/dev/null", "we"));
+
+        for (mode = 0; mode < _OUTPUT_MODE_MAX; mode++) {
+                if (!dev_null)
+                        log_info("/* %s */", output_mode_to_string(mode));
+                r = show_journal(dev_null ?: stdout, j, mode, 0, 0, -1, 0, NULL);
+                assert_se(r >= 0);
+
+                r = sd_journal_seek_head(j);
+                assert_se(r >= 0);
+        }
+
+        sd_journal_close(j);
+        unlink(name);
+
+        return 0;
+}
diff --git a/src/journal-remote/fuzz-journal-remote.options b/src/journal-remote/fuzz-journal-remote.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
diff --git a/src/journal/fuzz-journald-audit.c b/src/journal/fuzz-journald-audit.c
new file mode 100644 (file)
index 0000000..6e8e180
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fuzz.h"
+#include "fuzz-journald.h"
+#include "journald-audit.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        Server s;
+
+        dummy_server_init(&s, data, size);
+        process_audit_string(&s, 0, s.buffer, size);
+        server_done(&s);
+
+        return 0;
+}
diff --git a/src/journal/fuzz-journald-kmsg.c b/src/journal/fuzz-journald-kmsg.c
new file mode 100644 (file)
index 0000000..1b423d5
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fuzz.h"
+#include "fuzz-journald.h"
+#include "journald-kmsg.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        Server s;
+
+        if (size == 0)
+                return 0;
+
+        dummy_server_init(&s, data, size);
+        dev_kmsg_record(&s, s.buffer, size);
+        server_done(&s);
+
+        return 0;
+}
diff --git a/src/journal/fuzz-journald-native-fd.c b/src/journal/fuzz-journald-native-fd.c
new file mode 100644 (file)
index 0000000..fcfc5df
--- /dev/null
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fd-util.h"
+#include "fs-util.h"
+#include "fuzz-journald.h"
+#include "fuzz.h"
+#include "journald-native.h"
+#include "memfd-util.h"
+#include "process-util.h"
+#include "tmpfile-util.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        Server s;
+        _cleanup_close_ int sealed_fd = -1, unsealed_fd = -1;
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/fuzz-journald-native-fd.XXXXXX";
+        char *label = NULL;
+        size_t label_len = 0;
+        struct ucred ucred;
+        struct timeval *tv = NULL;
+
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
+                log_set_max_level(LOG_CRIT);
+
+        dummy_server_init(&s, NULL, 0);
+
+        sealed_fd = memfd_new(NULL);
+        assert_se(sealed_fd >= 0);
+        assert_se(write(sealed_fd, data, size) == (ssize_t) size);
+        assert_se(memfd_set_sealed(sealed_fd) >= 0);
+        assert_se(lseek(sealed_fd, 0, SEEK_SET) == 0);
+        ucred = (struct ucred) {
+                .pid = getpid_cached(),
+                .uid = geteuid(),
+                .gid = getegid(),
+        };
+        server_process_native_file(&s, sealed_fd, &ucred, tv, label, label_len);
+
+        unsealed_fd = mkostemp_safe(name);
+        assert_se(unsealed_fd >= 0);
+        assert_se(write(unsealed_fd, data, size) == (ssize_t) size);
+        assert_se(lseek(unsealed_fd, 0, SEEK_SET) == 0);
+        server_process_native_file(&s, unsealed_fd, &ucred, tv, label, label_len);
+
+        server_done(&s);
+
+        return 0;
+}
diff --git a/src/journal/fuzz-journald-native.c b/src/journal/fuzz-journald-native.c
new file mode 100644 (file)
index 0000000..6531c4f
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fuzz.h"
+#include "fuzz-journald.h"
+#include "journald-native.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        fuzz_journald_processing_function(data, size, server_process_native_message);
+        return 0;
+}
diff --git a/src/journal/fuzz-journald-stream.c b/src/journal/fuzz-journald-stream.c
new file mode 100644 (file)
index 0000000..038b335
--- /dev/null
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <linux/sockios.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include "fd-util.h"
+#include "fuzz.h"
+#include "fuzz-journald.h"
+#include "journald-stream.h"
+
+static int stream_fds[2] = { -1, -1 };
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        Server s;
+        StdoutStream *stream;
+        int v;
+
+        if (size == 0 || size > 65536)
+                return 0;
+
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
+                log_set_max_level(LOG_CRIT);
+
+        assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, stream_fds) >= 0);
+        dummy_server_init(&s, NULL, 0);
+        assert_se(stdout_stream_install(&s, stream_fds[0], &stream) >= 0);
+        assert_se(write(stream_fds[1], data, size) == (ssize_t) size);
+        while (ioctl(stream_fds[0], SIOCINQ, &v) == 0 && v)
+                sd_event_run(s.event, (uint64_t) -1);
+        if (s.n_stdout_streams)
+                stdout_stream_destroy(stream);
+        server_done(&s);
+        stream_fds[1] = safe_close(stream_fds[1]);
+
+        return 0;
+}
diff --git a/src/journal/fuzz-journald-stream.options b/src/journal/fuzz-journald-stream.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
diff --git a/src/journal/fuzz-journald-syslog.c b/src/journal/fuzz-journald-syslog.c
new file mode 100644 (file)
index 0000000..72ec610
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fuzz.h"
+#include "fuzz-journald.h"
+#include "journald-syslog.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        fuzz_journald_processing_function(data, size, server_process_syslog_message);
+        return 0;
+}
diff --git a/src/journal/fuzz-journald.c b/src/journal/fuzz-journald.c
new file mode 100644 (file)
index 0000000..e2f73ff
--- /dev/null
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "fuzz-journald.h"
+#include "journald-server.h"
+#include "sd-event.h"
+
+void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
+        *s = (Server) {
+                .syslog_fd = -1,
+                .native_fd = -1,
+                .stdout_fd = -1,
+                .dev_kmsg_fd = -1,
+                .audit_fd = -1,
+                .hostname_fd = -1,
+                .notify_fd = -1,
+                .storage = STORAGE_NONE,
+                .line_max = 64,
+        };
+        assert_se(sd_event_default(&s->event) >= 0);
+
+        if (buffer) {
+                s->buffer = memdup_suffix0(buffer, size);
+                assert_se(s->buffer);
+                s->buffer_size = size + 1;
+        }
+}
+
+void fuzz_journald_processing_function(
+                const uint8_t *data,
+                size_t size,
+                void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
+        ) {
+        Server s;
+        char *label = NULL;
+        size_t label_len = 0;
+        struct ucred *ucred = NULL;
+        struct timeval *tv = NULL;
+
+        if (size == 0)
+                return;
+
+        dummy_server_init(&s, data, size);
+        (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
+        server_done(&s);
+}
diff --git a/src/journal/fuzz-journald.h b/src/journal/fuzz-journald.h
new file mode 100644 (file)
index 0000000..4abb100
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "journald-server.h"
+
+void dummy_server_init(Server *s, const uint8_t *buffer, size_t size);
+
+void fuzz_journald_processing_function(
+                const uint8_t *data,
+                size_t size,
+                void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
+);
diff --git a/src/libsystemd-network/fuzz-dhcp-server.c b/src/libsystemd-network/fuzz-dhcp-server.c
new file mode 100644 (file)
index 0000000..c854d92
--- /dev/null
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "fuzz.h"
+
+#include "sd-dhcp-server.c"
+
+/* stub out network so that the server doesn't send */
+ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) {
+        return len;
+}
+
+ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) {
+        return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;
+        struct in_addr address = {.s_addr = htobe32(UINT32_C(10) << 24 | UINT32_C(1))};
+        static const uint8_t chaddr[] = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
+        uint8_t *client_id;
+        DHCPLease *lease;
+        int pool_offset;
+
+        if (size < sizeof(DHCPMessage))
+                return 0;
+
+        assert_se(sd_dhcp_server_new(&server, 1) >= 0);
+        server->fd = open("/dev/null", O_RDWR|O_CLOEXEC|O_NOCTTY);
+        assert_se(server->fd >= 0);
+        assert_se(sd_dhcp_server_configure_pool(server, &address, 24, 0, 0) >= 0);
+
+        /* add a lease to the pool to expose additional code paths */
+        client_id = malloc(2);
+        assert_se(client_id);
+        client_id[0] = 2;
+        client_id[1] = 2;
+        lease = new0(DHCPLease, 1);
+        assert_se(lease);
+        lease->client_id.length = 2;
+        lease->client_id.data = client_id;
+        lease->address = htobe32(UINT32_C(10) << 24 | UINT32_C(2));
+        lease->gateway = htobe32(UINT32_C(10) << 24 | UINT32_C(1));
+        lease->expiration = UINT64_MAX;
+        memcpy(lease->chaddr, chaddr, 16);
+        pool_offset = get_pool_offset(server, lease->address);
+        server->bound_leases[pool_offset] = lease;
+        assert_se(hashmap_put(server->leases_by_client_id, &lease->client_id, lease) >= 0);
+
+        (void) dhcp_server_handle_message(server, (DHCPMessage*)data, size);
+
+        return 0;
+}
diff --git a/src/libsystemd-network/fuzz-dhcp-server.options b/src/libsystemd-network/fuzz-dhcp-server.options
new file mode 100644 (file)
index 0000000..5c330e5
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 600
diff --git a/src/libsystemd-network/fuzz-dhcp6-client.c b/src/libsystemd-network/fuzz-dhcp6-client.c
new file mode 100644 (file)
index 0000000..e5e70dd
--- /dev/null
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <unistd.h>
+
+#include "sd-dhcp6-client.h"
+#include "sd-event.h"
+
+#include "dhcp6-internal.h"
+#include "dhcp6-protocol.h"
+#include "fd-util.h"
+#include "fuzz.h"
+
+static int test_dhcp_fd[2] = { -1, -1 };
+
+int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
+                                  const void *packet, size_t len) {
+        return len;
+}
+
+int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
+        assert_se(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_dhcp_fd) >= 0);
+        return test_dhcp_fd[0];
+}
+
+static void fuzz_client(const uint8_t *data, size_t size, bool is_information_request_enabled) {
+        _cleanup_(sd_event_unrefp) sd_event *e;
+        _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
+        struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } };
+
+        assert_se(sd_event_new(&e) >= 0);
+        assert_se(sd_dhcp6_client_new(&client) >= 0);
+        assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
+        assert_se(sd_dhcp6_client_set_ifindex(client, 42) == 0);
+        assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
+        assert_se(sd_dhcp6_client_set_information_request(client, is_information_request_enabled) == 0);
+
+        assert_se(sd_dhcp6_client_start(client) >= 0);
+
+        if (size >= sizeof(DHCP6Message))
+                assert_se(sd_dhcp6_client_set_transaction_id(client, htobe32(0x00ffffff) & ((const DHCP6Message *) data)->transaction_id) == 0);
+
+        assert_se(write(test_dhcp_fd[1], data, size) == (ssize_t) size);
+
+        sd_event_run(e, (uint64_t) -1);
+
+        assert_se(sd_dhcp6_client_stop(client) >= 0);
+
+        test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        if (size > 65536)
+                return 0;
+
+        /* This triggers client_receive_advertise */
+        fuzz_client(data, size, false);
+
+        /* This triggers client_receive_reply */
+        fuzz_client(data, size, true);
+
+        return 0;
+}
diff --git a/src/libsystemd-network/fuzz-dhcp6-client.options b/src/libsystemd-network/fuzz-dhcp6-client.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
diff --git a/src/libsystemd-network/fuzz-lldp.c b/src/libsystemd-network/fuzz-lldp.c
new file mode 100644 (file)
index 0000000..5747135
--- /dev/null
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "sd-event.h"
+#include "sd-lldp.h"
+
+#include "fd-util.h"
+#include "fuzz.h"
+#include "lldp-network.h"
+
+static int test_fd[2] = { -1, -1 };
+
+int lldp_network_bind_raw_socket(int ifindex) {
+        if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
+                return -errno;
+
+        return test_fd[0];
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+        _cleanup_(sd_lldp_unrefp) sd_lldp *lldp = NULL;
+
+        if (size > 2048)
+                return 0;
+
+        assert_se(sd_event_new(&e) == 0);
+        assert_se(sd_lldp_new(&lldp) >= 0);
+        assert_se(sd_lldp_set_ifindex(lldp, 42) >= 0);
+        assert_se(sd_lldp_attach_event(lldp, e, 0) >= 0);
+        assert_se(sd_lldp_start(lldp) >= 0);
+
+        assert_se(write(test_fd[1], data, size) == (ssize_t) size);
+        assert_se(sd_event_run(e, 0) >= 0);
+
+        assert_se(sd_lldp_stop(lldp) >= 0);
+        assert_se(sd_lldp_detach_event(lldp) >= 0);
+        test_fd[1] = safe_close(test_fd[1]);
+
+        return 0;
+}
diff --git a/src/libsystemd-network/fuzz-lldp.options b/src/libsystemd-network/fuzz-lldp.options
new file mode 100644 (file)
index 0000000..60bd9b0
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 2048
diff --git a/src/libsystemd-network/fuzz-ndisc-rs.c b/src/libsystemd-network/fuzz-ndisc-rs.c
new file mode 100644 (file)
index 0000000..d74cd2f
--- /dev/null
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <arpa/inet.h>
+#include <netinet/icmp6.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "icmp6-util.h"
+#include "fuzz.h"
+#include "sd-ndisc.h"
+#include "socket-util.h"
+#include "ndisc-internal.h"
+
+static int test_fd[2] = { -1, -1 };
+
+int icmp6_bind_router_solicitation(int index) {
+        assert_se(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
+        return test_fd[0];
+}
+
+int icmp6_bind_router_advertisement(int index) {
+        return -ENOSYS;
+}
+
+int icmp6_receive(int fd, void *iov_base, size_t iov_len,
+                  struct in6_addr *dst, triple_timestamp *timestamp) {
+        assert_se(read(fd, iov_base, iov_len) == (ssize_t) iov_len);
+
+        if (timestamp)
+                triple_timestamp_get(timestamp);
+
+        return 0;
+}
+
+int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
+        return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        struct ether_addr mac_addr = {
+                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
+        };
+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+        _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL;
+
+        if (size > 2048)
+                return 0;
+
+        assert_se(sd_event_new(&e) >= 0);
+        assert_se(sd_ndisc_new(&nd) >= 0);
+        assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0);
+        assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0);
+        assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0);
+        assert_se(sd_ndisc_start(nd) >= 0);
+        assert_se(write(test_fd[1], data, size) == (ssize_t) size);
+        (void) sd_event_run(e, (uint64_t) -1);
+        assert_se(sd_ndisc_stop(nd) >= 0);
+        close(test_fd[1]);
+
+        return 0;
+}
diff --git a/src/libsystemd-network/fuzz-ndisc-rs.options b/src/libsystemd-network/fuzz-ndisc-rs.options
new file mode 100644 (file)
index 0000000..60bd9b0
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 2048
diff --git a/src/nspawn/fuzz-nspawn-oci.c b/src/nspawn/fuzz-nspawn-oci.c
new file mode 100644 (file)
index 0000000..cfebf65
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fuzz.h"
+#include "nspawn-oci.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_(settings_freep) Settings *s = NULL;
+
+        if (size == 0)
+                return 0;
+
+        f = fmemopen_unlocked((char*) data, size, "re");
+        assert_se(f);
+
+        /* 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);
+
+        (void) oci_load(f, "/dev/null", &s);
+
+        return 0;
+}
diff --git a/src/nspawn/fuzz-nspawn-oci.options b/src/nspawn/fuzz-nspawn-oci.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
diff --git a/src/nspawn/fuzz-nspawn-settings.c b/src/nspawn/fuzz-nspawn-settings.c
new file mode 100644 (file)
index 0000000..bd98ed2
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fuzz.h"
+#include "nspawn-settings.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_(settings_freep) Settings *s = NULL;
+
+        if (size == 0)
+                return 0;
+
+        f = fmemopen_unlocked((char*) data, size, "re");
+        assert_se(f);
+
+        /* 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);
+
+        (void) settings_load(f, "/dev/null", &s);
+
+        return 0;
+}
diff --git a/src/nspawn/fuzz-nspawn-settings.options b/src/nspawn/fuzz-nspawn-settings.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
diff --git a/src/resolve/fuzz-dns-packet.c b/src/resolve/fuzz-dns-packet.c
new file mode 100644 (file)
index 0000000..b9a0aa1
--- /dev/null
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "fuzz.h"
+#include "memory-util.h"
+#include "resolved-dns-packet.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+
+        if (size > DNS_PACKET_SIZE_MAX)
+                return 0;
+
+        assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, 0, DNS_PACKET_SIZE_MAX) >= 0);
+        p->size = 0; /* by default append starts after the header, undo that */
+        assert_se(dns_packet_append_blob(p, data, size, NULL) >= 0);
+        if (size < DNS_PACKET_HEADER_SIZE) {
+                /* make sure we pad the packet back up to the minimum header size */
+                assert_se(p->allocated >= DNS_PACKET_HEADER_SIZE);
+                memzero(DNS_PACKET_DATA(p) + size, DNS_PACKET_HEADER_SIZE - size);
+                p->size = DNS_PACKET_HEADER_SIZE;
+        }
+        (void) dns_packet_extract(p);
+
+        return 0;
+}
diff --git a/src/resolve/fuzz-dns-packet.options b/src/resolve/fuzz-dns-packet.options
new file mode 100644 (file)
index 0000000..0824b19
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65535
diff --git a/src/udev/fuzz-udev-rule-parse-value.c b/src/udev/fuzz-udev-rule-parse-value.c
new file mode 100644 (file)
index 0000000..404d0cd
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <string.h>
+
+#include "alloc-util.h"
+#include "fuzz.h"
+#include "udev-util.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_free_ char *str = NULL;
+        int r;
+        char *value = UINT_TO_PTR(0x12345678U);
+        char *endpos = UINT_TO_PTR(0x87654321U);
+
+        assert_se(str = malloc(size + 1));
+        memcpy(str, data, size);
+        str[size] = '\0';
+
+        r = udev_rule_parse_value(str, &value, &endpos);
+
+        if (r < 0) {
+                /* not modified on failure */
+                assert_se(value == UINT_TO_PTR(0x12345678U));
+                assert_se(endpos == UINT_TO_PTR(0x87654321U));
+        } else {
+                assert_se(endpos <= str + size);
+                assert_se(endpos > str + 1);
+        }
+
+        return 0;
+}
diff --git a/src/udev/fuzz-udev-rules.c b/src/udev/fuzz-udev-rules.c
new file mode 100644 (file)
index 0000000..e1140bc
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <stdio.h>
+
+#include "fd-util.h"
+#include "fs-util.h"
+#include "fuzz.h"
+#include "tests.h"
+#include "tmpfile-util.h"
+#include "udev-rules.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        _cleanup_(udev_rules_freep) UdevRules *rules = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_(unlink_tempfilep) char filename[] = "/tmp/fuzz-udev-rules.XXXXXX";
+        int r;
+
+        if (!getenv("SYSTEMD_LOG_LEVEL")) {
+                log_set_max_level_realm(LOG_REALM_UDEV, LOG_CRIT);
+                log_set_max_level_realm(LOG_REALM_SYSTEMD, LOG_CRIT);
+        }
+
+        assert_se(fmkostemp_safe(filename, "r+", &f) == 0);
+        if (size != 0)
+                assert_se(fwrite(data, size, 1, f) == 1);
+        fflush(f);
+
+        assert_se(rules = udev_rules_new(RESOLVE_NAME_EARLY));
+        r = udev_rules_parse_file(rules, filename);
+        log_info_errno(r, "Parsing %s: %m", filename);
+        assert_se(IN_SET(r,
+                         0,       /* OK */
+                         -ENOBUFS /* line length exceeded */));
+
+        return 0;
+}
diff --git a/src/udev/fuzz-udev-rules.options b/src/udev/fuzz-udev-rules.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536