From 8b50b3198b40524be6f55301479bdf0115bc30c5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 6 Oct 2023 13:22:04 +0900 Subject: [PATCH 1/2] libsystemd-network: introduce $SYSTEMD_NETWORK_TEST_MODE environment variable Then, drop dhcp_client_set_test_mode() and friends. --- src/libsystemd-network/dhcp-identifier.c | 6 +++++- src/libsystemd-network/dhcp-identifier.h | 2 +- src/libsystemd-network/dhcp-internal.h | 2 -- src/libsystemd-network/dhcp6-internal.h | 4 ---- src/libsystemd-network/fuzz-dhcp-client.c | 3 ++- src/libsystemd-network/fuzz-dhcp6-client.c | 3 ++- src/libsystemd-network/network-common.c | 19 +++++++++++++++++++ src/libsystemd-network/network-common.h | 2 ++ src/libsystemd-network/sd-dhcp-client.c | 11 +---------- src/libsystemd-network/sd-dhcp6-client.c | 12 +++--------- src/libsystemd-network/test-dhcp-client.c | 6 +++--- src/libsystemd-network/test-dhcp6-client.c | 8 ++++++-- 12 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c index c905704ab5e..f65cdbecde5 100644 --- a/src/libsystemd-network/dhcp-identifier.c +++ b/src/libsystemd-network/dhcp-identifier.c @@ -6,6 +6,7 @@ #include "dhcp-identifier.h" #include "netif-util.h" +#include "network-common.h" #include "siphash24.h" #include "sparse-endian.h" #include "string-table.h" @@ -90,14 +91,17 @@ int dhcp_identifier_set_duid_ll( return 0; } -int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *ret_len) { +int dhcp_identifier_set_duid_en(struct duid *ret_duid, size_t *ret_len) { sd_id128_t machine_id; + bool test_mode; uint64_t hash; int r; assert(ret_duid); assert(ret_len); + test_mode = network_test_mode_enabled(); + if (!test_mode) { r = sd_id128_get_machine(&machine_id); if (r < 0) diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h index 7b36f92e7fa..5ffa38dfc8b 100644 --- a/src/libsystemd-network/dhcp-identifier.h +++ b/src/libsystemd-network/dhcp-identifier.h @@ -70,7 +70,7 @@ int dhcp_identifier_set_duid_ll( uint16_t arp_type, struct duid *ret_duid, size_t *ret_len); -int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *ret_len); +int dhcp_identifier_set_duid_en(struct duid *ret_duid, size_t *ret_len); int dhcp_identifier_set_duid_uuid(struct duid *ret_duid, size_t *ret_len); int dhcp_identifier_set_duid_raw( DUIDType duid_type, diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h index d4e4a026b52..b027b6faf05 100644 --- a/src/libsystemd-network/dhcp-internal.h +++ b/src/libsystemd-network/dhcp-internal.h @@ -72,8 +72,6 @@ void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr, int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port); -void dhcp_client_set_test_mode(sd_dhcp_client *client, bool test_mode); - /* If we are invoking callbacks of a dhcp-client, ensure unreffing the * client from the callback doesn't destroy the object we are working * on */ diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h index 97bc82d5210..e5b3b1302c1 100644 --- a/src/libsystemd-network/dhcp6-internal.h +++ b/src/libsystemd-network/dhcp6-internal.h @@ -83,9 +83,6 @@ struct sd_dhcp6_client { sd_dhcp6_client_callback_t state_callback; void *state_userdata; bool send_release; - - /* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */ - bool test_mode; }; int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address); @@ -93,7 +90,6 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *address, const void *packet, size_t len); int dhcp6_client_send_message(sd_dhcp6_client *client); -void dhcp6_client_set_test_mode(sd_dhcp6_client *client, bool test_mode); int dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id); #define log_dhcp6_client_errno(client, error, fmt, ...) \ diff --git a/src/libsystemd-network/fuzz-dhcp-client.c b/src/libsystemd-network/fuzz-dhcp-client.c index 9b9e741e534..bdd8a483a15 100644 --- a/src/libsystemd-network/fuzz-dhcp-client.c +++ b/src/libsystemd-network/fuzz-dhcp-client.c @@ -54,6 +54,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { _cleanup_(sd_event_unrefp) sd_event *e = NULL; int res, r; + assert_se(setenv("SYSTEMD_NETWORK_TEST_MODE", "1", 1) >= 0); + if (!getenv("SYSTEMD_LOG_LEVEL")) log_set_max_level(LOG_CRIT); @@ -68,7 +70,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, mac_addr, bcast_addr, ETH_ALEN, ARPHRD_ETHER) >= 0); - dhcp_client_set_test_mode(client, true); res = sd_dhcp_client_start(client); assert_se(IN_SET(res, 0, -EINPROGRESS)); diff --git a/src/libsystemd-network/fuzz-dhcp6-client.c b/src/libsystemd-network/fuzz-dhcp6-client.c index 356a9f48fd1..02f556709c0 100644 --- a/src/libsystemd-network/fuzz-dhcp6-client.c +++ b/src/libsystemd-network/fuzz-dhcp6-client.c @@ -73,6 +73,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { struct in6_addr hint = { { { 0x3f, 0xfe, 0x05, 0x01, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }; static const char *v1_data = "hogehoge", *v2_data = "foobar"; + assert_se(setenv("SYSTEMD_NETWORK_TEST_MODE", "1", 1) >= 0); + if (outside_size_range(size, 0, 65536)) return 0; @@ -81,7 +83,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 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); - dhcp6_client_set_test_mode(client, true); /* Used when sending message. */ assert_se(sd_dhcp6_client_set_fqdn(client, "example.com") == 1); diff --git a/src/libsystemd-network/network-common.c b/src/libsystemd-network/network-common.c index be77d7e0a6e..b23cb8c3533 100644 --- a/src/libsystemd-network/network-common.c +++ b/src/libsystemd-network/network-common.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "env-util.h" #include "format-util.h" #include "network-common.h" #include "unaligned.h" @@ -93,3 +94,21 @@ usec_t time_span_to_stamp(usec_t span, usec_t base) { return usec_add(base, span); } + +bool network_test_mode_enabled(void) { + static int test_mode = -1; + int r; + + if (test_mode < 0) { + r = getenv_bool("SYSTEMD_NETWORK_TEST_MODE"); + if (r < 0) { + if (r != -ENXIO) + log_debug_errno(r, "Failed to parse $SYSTEMD_NETWORK_TEST_MODE environment variable, ignoring: %m"); + + test_mode = false; + } else + test_mode = r; + } + + return test_mode; +} diff --git a/src/libsystemd-network/network-common.h b/src/libsystemd-network/network-common.h index cf3d1e01304..f71da63b786 100644 --- a/src/libsystemd-network/network-common.h +++ b/src/libsystemd-network/network-common.h @@ -39,3 +39,5 @@ be32_t usec_to_be32_sec(usec_t t); be32_t usec_to_be32_msec(usec_t t); be16_t usec_to_be16_sec(usec_t t); usec_t time_span_to_stamp(usec_t span, usec_t base); + +bool network_test_mode_enabled(void); diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 79f308f6528..facb2b2424a 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -125,9 +125,6 @@ struct sd_dhcp_client { int ip_service_type; int socket_priority; bool socket_priority_set; - - /* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */ - bool test_mode; }; static const uint8_t default_req_opts[] = { @@ -507,7 +504,7 @@ int sd_dhcp_client_set_iaid_duid_en( if (r < 0) return r; - r = dhcp_identifier_set_duid_en(client->test_mode, &client->client_id.ns.duid, &len); + r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len); if (r < 0) return log_dhcp_client_errno(client, r, "Failed to set DUID-EN: %m"); @@ -568,12 +565,6 @@ int sd_dhcp_client_set_iaid_duid_raw( return 0; } -void dhcp_client_set_test_mode(sd_dhcp_client *client, bool test_mode) { - assert(client); - - client->test_mode = test_mode; -} - int sd_dhcp_client_set_hostname( sd_dhcp_client *client, const char *hostname) { diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 4c500fc4a92..d2402e676a7 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -194,7 +194,7 @@ static int client_ensure_duid(sd_dhcp6_client *client) { if (client->duid_len != 0) return 0; - return dhcp_identifier_set_duid_en(client->test_mode, &client->duid, &client->duid_len); + return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len); } /** @@ -234,7 +234,7 @@ int sd_dhcp6_client_set_duid_en(sd_dhcp6_client *client) { assert_return(client, -EINVAL); assert_return(!sd_dhcp6_client_is_running(client), -EBUSY); - r = dhcp_identifier_set_duid_en(client->test_mode, &client->duid, &client->duid_len); + r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len); if (r < 0) return log_dhcp6_client_errno(client, r, "Failed to set DUID-EN: %m"); @@ -348,12 +348,6 @@ int sd_dhcp6_client_get_iaid(sd_dhcp6_client *client, uint32_t *iaid) { return 0; } -void dhcp6_client_set_test_mode(sd_dhcp6_client *client, bool test_mode) { - assert(client); - - client->test_mode = test_mode; -} - int sd_dhcp6_client_set_fqdn( sd_dhcp6_client *client, const char *fqdn) { @@ -504,7 +498,7 @@ int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request) { int dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id) { assert(client); - assert(client->test_mode); + assert_se(network_test_mode_enabled()); /* This is for tests or fuzzers. */ diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index f3f558a3585..912d4493f54 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -168,7 +168,7 @@ static int check_options(uint8_t code, uint8_t len, const void *option, void *us struct duid duid; size_t duid_len; - assert_se(dhcp_identifier_set_duid_en(/* test_mode = */ true, &duid, &duid_len) >= 0); + assert_se(dhcp_identifier_set_duid_en(&duid, &duid_len) >= 0); assert_se(dhcp_identifier_set_iaid(NULL, &hw_addr, /* legacy = */ true, &iaid) >= 0); assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len); @@ -291,7 +291,6 @@ static void test_discover_message(sd_event *e) { assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, hw_addr.bytes, bcast_addr.bytes, hw_addr.length, ARPHRD_ETHER) >= 0); - dhcp_client_set_test_mode(client, true); assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0); @@ -509,7 +508,6 @@ static void test_addr_acq(sd_event *e) { assert_se(sd_dhcp_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp_client_set_mac(client, hw_addr.bytes, bcast_addr.bytes, hw_addr.length, ARPHRD_ETHER) >= 0); - dhcp_client_set_test_mode(client, true); assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e) >= 0); @@ -537,6 +535,8 @@ static void test_addr_acq(sd_event *e) { int main(int argc, char *argv[]) { _cleanup_(sd_event_unrefp) sd_event *e; + assert_se(setenv("SYSTEMD_NETWORK_TEST_MODE", "1", 1) >= 0); + test_setup_logging(LOG_DEBUG); assert_se(sd_event_new(&e) >= 0); diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c index 7c253b5e5f7..bf9c3f409e0 100644 --- a/src/libsystemd-network/test-dhcp6-client.c +++ b/src/libsystemd-network/test-dhcp6-client.c @@ -1073,7 +1073,6 @@ TEST(dhcp6_client) { assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") >= 0); assert_se(sd_dhcp6_client_set_iaid(client, unaligned_read_be32((uint8_t[]) { IA_ID_BYTES })) >= 0); assert_se(sd_dhcp6_client_set_send_release(client, true) >= 0); - dhcp6_client_set_test_mode(client, true); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVER) >= 0); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN) >= 0); @@ -1097,4 +1096,9 @@ TEST(dhcp6_client) { test_fd[1] = safe_close(test_fd[1]); } -DEFINE_TEST_MAIN(LOG_DEBUG); +static int intro(void) { + assert_se(setenv("SYSTEMD_NETWORK_TEST_MODE", "1", 1) >= 0); + return 0; +} + +DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro); From 042c91459aa234c9ce3b3ece0fdad8ba568018f2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 6 Oct 2023 13:26:16 +0900 Subject: [PATCH 2/2] fuzz: suppress log messages --- src/libsystemd-network/fuzz-dhcp6-client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libsystemd-network/fuzz-dhcp6-client.c b/src/libsystemd-network/fuzz-dhcp6-client.c index 02f556709c0..204c0e15d23 100644 --- a/src/libsystemd-network/fuzz-dhcp6-client.c +++ b/src/libsystemd-network/fuzz-dhcp6-client.c @@ -75,6 +75,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { assert_se(setenv("SYSTEMD_NETWORK_TEST_MODE", "1", 1) >= 0); + if (!getenv("SYSTEMD_LOG_LEVEL")) + log_set_max_level(LOG_CRIT); + if (outside_size_range(size, 0, 65536)) return 0;