diff mbox series

[1/6] net: Allow padding in net_domain_list_parse

Message ID 20220920133201.3303119-1-andrew.zaborowski@intel.com (mailing list archive)
State Accepted, archived
Headers show
Series [1/6] net: Allow padding in net_domain_list_parse | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
prestwoj/iwd-ci-makedistcheck success Make Distcheck
prestwoj/iwd-ci-build success Build - Configure
prestwoj/iwd-ci-clang success clang PASS
prestwoj/iwd-ci-makecheckvalgrind success Make Check w/Valgrind
prestwoj/iwd-ci-makecheck success Make Check
prestwoj/iwd-ci-testrunner fail test-runner - FAIL:

Commit Message

Andrew Zaborowski Sept. 20, 2022, 1:31 p.m. UTC
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")
---
 ell/dhcp6-lease.c | 2 +-
 ell/icmp6.c       | 6 +++---
 ell/net-private.h | 2 +-
 ell/net.c         | 8 +++++++-
 4 files changed, 12 insertions(+), 6 deletions(-)

Comments

Denis Kenzior Sept. 20, 2022, 3:06 p.m. UTC | #1
Hi Andrew,

On 9/20/22 08:31, Andrew Zaborowski wrote:
> 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")
> ---
>   ell/dhcp6-lease.c | 2 +-
>   ell/icmp6.c       | 6 +++---
>   ell/net-private.h | 2 +-
>   ell/net.c         | 8 +++++++-
>   4 files changed, 12 insertions(+), 6 deletions(-)
> 

All applied, thanks.

Regards,
-Denis
diff mbox series

Patch

diff --git a/ell/dhcp6-lease.c b/ell/dhcp6-lease.c
index 978176a..a92cff9 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 a2765ea..5ddc494 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 39d4d98..a864034 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)
diff --git a/ell/net.c b/ell/net.c
index 378b9f2..aa7fc20 100644
--- a/ell/net.c
+++ b/ell/net.c
@@ -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;