diff options
author | Evgeny Vereshchagin <evvers@ya.ru> | 2018-09-26 03:10:53 +0000 |
---|---|---|
committer | Evgeny Vereshchagin <evvers@ya.ru> | 2018-09-29 02:27:07 +0000 |
commit | d89a400ed664e0b57fd8667db5637792a185e831 (patch) | |
tree | 2eef30a9741790dcbd6255af59bdee2ba88429d7 | |
parent | 6cc2b882751bdc1f70520ffd93830357b318a9e5 (diff) | |
download | systemd-d89a400ed664e0b57fd8667db5637792a185e831.tar.gz |
fuzz: add a fuzzer for dhcp6_client
-rw-r--r-- | src/fuzz/fuzz-dhcp6-client.c | 59 | ||||
-rw-r--r-- | src/fuzz/meson.build | 9 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp6-client.c | 8 | ||||
-rw-r--r-- | src/systemd/sd-dhcp6-client.h | 2 |
4 files changed, 78 insertions, 0 deletions
diff --git a/src/fuzz/fuzz-dhcp6-client.c b/src/fuzz/fuzz-dhcp6-client.c new file mode 100644 index 0000000000..32a3c30643 --- /dev/null +++ b/src/fuzz/fuzz-dhcp6-client.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#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]; + +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, 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) { + /* 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/meson.build b/src/fuzz/meson.build index f66d8883c4..066737c175 100644 --- a/src/fuzz/meson.build +++ b/src/fuzz/meson.build @@ -9,6 +9,15 @@ 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'], + [libshared, + libsystemd_network], + []], + [['src/fuzz/fuzz-dhcp-server.c'], [libsystemd_network, libshared], diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index b793fc0285..9c097cc334 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -368,6 +368,14 @@ int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request) { return 0; } +int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, be32_t transaction_id) { + assert_return(client, -EINVAL); + + client->transaction_id = transaction_id; + + return 0; +} + int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) { assert_return(client, -EINVAL); diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index 7024ad84d6..639339d181 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -25,6 +25,7 @@ #include "sd-dhcp6-lease.h" #include "sd-event.h" +#include "sparse-endian.h" #include "_sd-common.h" @@ -127,6 +128,7 @@ int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client, int *request); int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request); +int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, be32_t transaction_id); int sd_dhcp6_client_get_lease( sd_dhcp6_client *client, |