From f54f473b3663ac6e12d25cbbe7ca15f67742406b Mon Sep 17 00:00:00 2001 From: Ronan Pigott Date: Mon, 28 Oct 2024 20:33:35 -0700 Subject: [PATCH 1/2] network: add missing else in dhcp_lease_load Fixes: 3fd6708cde0f (network: Serialize DNR servers) --- src/libsystemd-network/sd-dhcp-lease.c | 3 ++- test/fuzz/fuzz-dhcp-client/dnr_invalid | Bin 0 -> 311 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/fuzz/fuzz-dhcp-client/dnr_invalid diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 1c0cd6829b..6b2d810645 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -1551,7 +1551,8 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { r = deserialize_dnr(&lease->dnr, dnr); if (r < 0) log_debug_errno(r, "Failed to deserialize DNR servers %s, ignoring: %m", dnr); - lease->n_dnr = r; + else + lease->n_dnr = r; } if (ntp) { diff --git a/test/fuzz/fuzz-dhcp-client/dnr_invalid b/test/fuzz/fuzz-dhcp-client/dnr_invalid new file mode 100644 index 0000000000000000000000000000000000000000..a988fba04607d12a8dc75c76c567314d5888d82b GIT binary patch literal 311 zcmY#TpfdQ6)x7@@;s0QORRvjs$d)0q5r&~#Y|6-F%mR`&1Cxu)7$g-GIGKS0Aj|+3 SWME`qVNS^}L6(X^l>z|MMK?hJ literal 0 HcmV?d00001 From b31b99d76fa221bd2f01f593e8426d64fa1b40d1 Mon Sep 17 00:00:00 2001 From: Ronan Pigott Date: Mon, 28 Oct 2024 21:26:51 -0700 Subject: [PATCH 2/2] network: Restrict the valid charset of DNR names Not all possible DNS names will survive serialization. Restrict the set of valid dns names to LDH encoded names. Fixes: 25c33e350042 (network: parse RFC9463 DHCPv4 DNR option, 2024-01-16) Fixes: a07e83cc58f6 (network: Parse RFC9463 DHCPv6 DNR option, 2024-01-17) Fixes: 0c90d1d2f243 (ndisc: Parse RFC9463 encrypted DNS (DNR) option, 2024-01-19) --- src/libsystemd-network/ndisc-option.c | 5 +++++ src/libsystemd-network/sd-dhcp-lease.c | 5 +++++ src/libsystemd-network/sd-dhcp6-lease.c | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/src/libsystemd-network/ndisc-option.c b/src/libsystemd-network/ndisc-option.c index 1071d98b19..d784ffb3ff 100644 --- a/src/libsystemd-network/ndisc-option.c +++ b/src/libsystemd-network/ndisc-option.c @@ -1358,6 +1358,11 @@ static int ndisc_option_parse_encrypted_dns(Set **options, size_t offset, size_t r = ndisc_get_dns_name(opt + off, ilen, &res.auth_name); if (r < 0) return r; + r = dns_name_is_valid_ldh(res.auth_name); + if (r < 0) + return r; + if (!r) + return -EBADMSG; if (dns_name_is_root(res.auth_name)) return -EBADMSG; off += ilen; diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 6b2d810645..fc891a0b04 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -628,6 +628,11 @@ static int lease_parse_dnr(const uint8_t *option, size_t len, sd_dns_resolver ** r = lease_parse_dns_name(option + offset, ilen, &res.auth_name); if (r < 0) return r; + r = dns_name_is_valid_ldh(res.auth_name); + if (r < 0) + return r; + if (!r) + return -EBADMSG; if (dns_name_is_root(res.auth_name)) return -EBADMSG; offset += ilen; diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index bc054c42b2..2ff1e87a2e 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -8,6 +8,7 @@ #include "alloc-util.h" #include "dhcp6-internal.h" #include "dhcp6-lease-internal.h" +#include "dns-domain.h" #include "network-common.h" #include "sort-util.h" #include "strv.h" @@ -465,6 +466,11 @@ static int dhcp6_lease_add_dnr(sd_dhcp6_lease *lease, const uint8_t *optval, siz r = dhcp6_option_parse_domainname(optval + offset, ilen, &res.auth_name); if (r < 0) return r; + r = dns_name_is_valid_ldh(res.auth_name); + if (r < 0) + return r; + if (!r) + return -EBADMSG; offset += ilen; /* RFC9463 ยง 3.1.6: adn only mode */