diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2022-09-20 15:31:56 +0200 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2022-09-20 10:01:54 -0500 |
commit | c79b047c99cfce63614a615e27ccd09ec4ed2748 (patch) | |
tree | 883da24cbea68b9520415468ad2ed016ea22f9b4 | |
parent | 04fe608a3e67a390c852b3b3bfb95b0b9bbf948d (diff) |
net: Allow padding in net_domain_list_parse
The domain name lists in ICMPv6 options may be 0-padded meaning that a
0-byte at the beginning of a domain record (ie. a domain with no labels)
is allowed and should be treated as the end of the list. Add a boolean
parameter to tell net_domain_list_parse() whether to allow this.
Fixes: 4b1ce9b3e3d0 ("icmp6: Parse RDNSS and DNSSL options")
-rw-r--r-- | ell/dhcp6-lease.c | 2 | ||||
-rw-r--r-- | ell/icmp6.c | 6 | ||||
-rw-r--r-- | ell/net-private.h | 2 | ||||
-rw-r--r-- | ell/net.c | 8 |
4 files changed, 12 insertions, 6 deletions
diff --git a/ell/dhcp6-lease.c b/ell/dhcp6-lease.c index 978176ae..a92cff9f 100644 --- a/ell/dhcp6-lease.c +++ b/ell/dhcp6-lease.c @@ -312,7 +312,7 @@ struct l_dhcp6_lease *_dhcp6_lease_parse_options( lease->rapid_commit = true; break; case L_DHCP6_OPTION_DOMAIN_LIST: - lease->domain_list = net_domain_list_parse(v, l); + lease->domain_list = net_domain_list_parse(v, l, false); if (!lease->domain_list) goto error; diff --git a/ell/icmp6.c b/ell/icmp6.c index a2765ea7..5ddc494d 100644 --- a/ell/icmp6.c +++ b/ell/icmp6.c @@ -1104,11 +1104,11 @@ struct l_icmp6_router *_icmp6_router_parse(const struct nd_router_advert *ra, { struct domain_info *info = &r->domains[n_domains]; _auto_(l_free) char **domain_list = - net_domain_list_parse(opts + 8, l - 8); + net_domain_list_parse(opts + 8, l - 8, true); char **i; - /* Ignore invalid option */ - if (!domain_list) + /* Ignore malformed option */ + if (!domain_list || !domain_list[0]) break; for (i = domain_list; *i; i++) { diff --git a/ell/net-private.h b/ell/net-private.h index 39d4d980..a8640341 100644 --- a/ell/net-private.h +++ b/ell/net-private.h @@ -21,7 +21,7 @@ */ char *net_domain_name_parse(const uint8_t *raw, size_t raw_len); -char **net_domain_list_parse(const uint8_t *raw, size_t raw_len); +char **net_domain_list_parse(const uint8_t *raw, size_t raw_len, bool padded); static inline const void *net_prefix_from_ipv6(const uint8_t *address, uint8_t prefix_len) @@ -295,7 +295,7 @@ char *net_domain_name_parse(const uint8_t *raw, size_t raw_len) /* * Parse list of domain names encoded according to RFC 1035 Section 3.1 */ -char **net_domain_list_parse(const uint8_t *raw, size_t raw_len) +char **net_domain_list_parse(const uint8_t *raw, size_t raw_len, bool padded) { size_t remaining = raw_len; const uint8_t *p = raw; @@ -305,6 +305,9 @@ char **net_domain_list_parse(const uint8_t *raw, size_t raw_len) struct l_string *growable = NULL; while (remaining) { + if (padded && p[0] == 0) + break; + r = validate_next_domain_name(p, remaining); if (r < 0) return NULL; @@ -323,6 +326,9 @@ char **net_domain_list_parse(const uint8_t *raw, size_t raw_len) remaining -= *p + 1; if (*p == 0) { + if (!growable) + break; + p += 1; ret[nitems++] = l_string_unwrap(growable); growable = NULL; |