From c3da2e4732a89bceecde57e15a86948a34ed8b79 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 24 Jan 2022 19:26:25 +0900 Subject: [PATCH 1/3] fuzz-dhcp-server: also set new lease elements correctly The fuzzer does not send anything to the address, so it should be not necessary, but just for safety. --- src/libsystemd-network/fuzz-dhcp-server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsystemd-network/fuzz-dhcp-server.c b/src/libsystemd-network/fuzz-dhcp-server.c index e90284f6f2..87add43270 100644 --- a/src/libsystemd-network/fuzz-dhcp-server.c +++ b/src/libsystemd-network/fuzz-dhcp-server.c @@ -44,7 +44,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 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); + lease->htype = ARPHRD_ETHER; + lease->hlen = ETH_ALEN; + memcpy(lease->chaddr, chaddr, ETH_ALEN); assert_se(hashmap_ensure_put(&server->bound_leases_by_client_id, &dhcp_lease_hash_ops, &lease->client_id, lease) >= 0); assert_se(hashmap_ensure_put(&server->bound_leases_by_address, NULL, UINT32_TO_PTR(lease->address), lease) >= 0); lease->server = server; From 0590f1b58c3e78be23a366403ba2c571e4521d0a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 24 Jan 2022 19:35:14 +0900 Subject: [PATCH 2/3] fuzz-dhcp-server: duplicate input data As `dhcp_server_handle_message()` -> `ensure_sane_request()` may modify the input data, and that causes error in some fuzzing engine. --- src/libsystemd-network/fuzz-dhcp-server.c | 5 ++++- ...se-minimized-fuzz-dhcp-server-4916534286352384 | Bin 0 -> 243 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 test/fuzz/fuzz-dhcp-server/clusterfuzz-testcase-minimized-fuzz-dhcp-server-4916534286352384 diff --git a/src/libsystemd-network/fuzz-dhcp-server.c b/src/libsystemd-network/fuzz-dhcp-server.c index 87add43270..15edec3efb 100644 --- a/src/libsystemd-network/fuzz-dhcp-server.c +++ b/src/libsystemd-network/fuzz-dhcp-server.c @@ -21,12 +21,15 @@ 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}; + _cleanup_free_ uint8_t *duped = NULL; uint8_t *client_id; DHCPLease *lease; if (size < sizeof(DHCPMessage)) return 0; + assert_se(duped = memdup(data, size)); + 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); @@ -51,7 +54,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { assert_se(hashmap_ensure_put(&server->bound_leases_by_address, NULL, UINT32_TO_PTR(lease->address), lease) >= 0); lease->server = server; - (void) dhcp_server_handle_message(server, (DHCPMessage*)data, size); + (void) dhcp_server_handle_message(server, (DHCPMessage*) duped, size); return 0; } diff --git a/test/fuzz/fuzz-dhcp-server/clusterfuzz-testcase-minimized-fuzz-dhcp-server-4916534286352384 b/test/fuzz/fuzz-dhcp-server/clusterfuzz-testcase-minimized-fuzz-dhcp-server-4916534286352384 new file mode 100644 index 0000000000000000000000000000000000000000..3d1370599695747e36f58ea290d8e1265b2b6b68 GIT binary patch literal 243 zcmZQnU{k;a7{CBYmf=4V2g<}EgsBKB!UUvYn1MlogDn#yP8~=RAdL)Q$O0CH Uuz{p07VQvMA-N64G-3P?02Z7f`v3p{ literal 0 HcmV?d00001 From bf2a8b7b13018e55dcaa8a50f07ffef6bc9c7919 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 25 Jan 2022 00:04:59 +0900 Subject: [PATCH 3/3] fuzz-dhcp-server: attach sd_event to make dhcp_server_cleanup_expired_leases() works in the fuzzer Otherwise, most code paths in dhcp_server_handle_message() are not evaluated by the fuzzer. --- src/libsystemd-network/fuzz-dhcp-server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsystemd-network/fuzz-dhcp-server.c b/src/libsystemd-network/fuzz-dhcp-server.c index 15edec3efb..6a57850992 100644 --- a/src/libsystemd-network/fuzz-dhcp-server.c +++ b/src/libsystemd-network/fuzz-dhcp-server.c @@ -31,6 +31,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { assert_se(duped = memdup(data, size)); assert_se(sd_dhcp_server_new(&server, 1) >= 0); + assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 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);