]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fuzz: introduce fuzzer for DHCP relay agent
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 2 May 2026 14:32:33 +0000 (23:32 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 21 May 2026 07:55:59 +0000 (16:55 +0900)
src/libsystemd-network/fuzz-dhcp-relay.c [new file with mode: 0644]
src/libsystemd-network/meson.build
test/fuzz/fuzz-dhcp-relay/discover [new file with mode: 0644]
test/fuzz/fuzz-dhcp-relay/offer [new file with mode: 0644]

diff --git a/src/libsystemd-network/fuzz-dhcp-relay.c b/src/libsystemd-network/fuzz-dhcp-relay.c
new file mode 100644 (file)
index 0000000..2c828b9
--- /dev/null
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <sys/socket.h>
+
+#include "sd-event.h"
+
+#include "dhcp-relay-internal.h"
+#include "fd-util.h"
+#include "fuzz.h"
+#include "in-addr-util.h"
+#include "iovec-util.h"
+#include "tests.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+        union in_addr_union a;
+
+        fuzz_setup_logging();
+
+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+        ASSERT_OK(sd_event_new(&e));
+
+        _cleanup_(sd_dhcp_relay_unrefp) sd_dhcp_relay *relay = NULL;
+        ASSERT_OK(sd_dhcp_relay_new(&relay));
+        ASSERT_OK(sd_dhcp_relay_attach_event(relay, e, SD_EVENT_PRIORITY_NORMAL));
+        ASSERT_OK(in_addr_from_string(AF_INET, "198.51.100.1", &a));
+        ASSERT_OK(sd_dhcp_relay_set_server_address(relay, &a.in));
+        ASSERT_OK(sd_dhcp_relay_set_remote_id(relay, &IOVEC_MAKE_STRING("test-remote-id")));
+        ASSERT_OK(sd_dhcp_relay_set_server_identifier_override(relay, true));
+
+        _cleanup_(sd_dhcp_relay_interface_unrefp) sd_dhcp_relay_interface *upstream = NULL;
+        ASSERT_OK(sd_dhcp_relay_add_interface(relay, 4242, /* is_upstream= */ true, &upstream));
+        ASSERT_OK(sd_dhcp_relay_interface_set_ifname(upstream, "test-upstream"));
+        ASSERT_OK(in_addr_from_string(AF_INET, "198.51.100.2", &a));
+        ASSERT_OK(sd_dhcp_relay_interface_set_address(upstream, &a.in, 24));
+
+        _cleanup_close_pair_ int upstream_fd[2] = EBADF_PAIR;
+        ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, upstream_fd));
+        upstream->socket_fd = TAKE_FD(upstream_fd[0]);
+        ASSERT_OK(sd_dhcp_relay_interface_start(upstream));
+
+        _cleanup_(sd_dhcp_relay_interface_unrefp) sd_dhcp_relay_interface *downstream = NULL;
+        ASSERT_OK(sd_dhcp_relay_add_interface(relay, 4343, /* is_upstream= */ false, &downstream));
+        ASSERT_OK(sd_dhcp_relay_interface_set_ifname(downstream, "test-downstream"));
+        ASSERT_OK(in_addr_from_string(AF_INET, "192.0.2.1", &a));
+        ASSERT_OK(sd_dhcp_relay_interface_set_address(downstream, &a.in, 24));
+
+        ASSERT_OK(in_addr_from_string(AF_INET, "203.0.113.1", &a));
+        ASSERT_OK(sd_dhcp_relay_downstream_set_gateway_address(downstream, &a.in));
+        ASSERT_OK(sd_dhcp_relay_downstream_set_circuit_id(downstream, &IOVEC_MAKE_STRING("test-circuit-id")));
+        ASSERT_OK(sd_dhcp_relay_downstream_set_virtual_subnet_selection(downstream, &IOVEC_MAKE_STRING("test-virtual-net")));
+
+        _cleanup_close_pair_ int downstream_fd[2] = EBADF_PAIR;
+        ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, downstream_fd));
+        downstream->socket_fd = TAKE_FD(downstream_fd[0]);
+        ASSERT_OK(sd_dhcp_relay_interface_start(downstream));
+
+        (void) downstream_process_message(downstream, &IOVEC_MAKE(data, size), /* pktinfo= */ NULL);
+        (void) upstream_process_message(upstream, &IOVEC_MAKE(data, size), /* pktinfo= */ NULL);
+
+        return 0;
+}
index 7693687a132116bf986eef5243abde15c7f929f7..5d2368cc9881a10810962dfcc4849ab1b5689e33 100644 (file)
@@ -136,6 +136,9 @@ executables += [
         network_fuzz_template + {
                 'sources' : files('fuzz-dhcp-client.c'),
         },
+        network_fuzz_template + {
+                'sources' : files('fuzz-dhcp-relay.c'),
+        },
         network_fuzz_template + {
                 'sources' : files('fuzz-dhcp6-client.c'),
         },
diff --git a/test/fuzz/fuzz-dhcp-relay/discover b/test/fuzz/fuzz-dhcp-relay/discover
new file mode 100644 (file)
index 0000000..4ffce39
Binary files /dev/null and b/test/fuzz/fuzz-dhcp-relay/discover differ
diff --git a/test/fuzz/fuzz-dhcp-relay/offer b/test/fuzz/fuzz-dhcp-relay/offer
new file mode 100644 (file)
index 0000000..fe11025
Binary files /dev/null and b/test/fuzz/fuzz-dhcp-relay/offer differ