summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-10-19 03:42:10 +0900
committerThomas Haller <thaller@redhat.com>2018-10-29 21:18:43 +0100
commitd589df063996f05b22ef30773fb85efde4531489 (patch)
tree2b5f47fc2ad1f4b75647527c5aa3497086c6acd3
parent77d882583d975a1a671ddc9fb91d13255331ce10 (diff)
downloadNetworkManager-d589df063996f05b22ef30773fb85efde4531489.tar.gz
sd-dhcp6: make dhcp6_option_parse_domainname() not store empty domain
This improves performance of fuzzer. C.f. oss-fuzz#11019. (cherry picked from commit 3c72b6ed4252e7ff5f7704bfe44557ec197b47fa) (cherry picked from commit 50403cccee28c7dcd54b138a0d3b3f69ea0204fe) (cherry picked from commit f11f5abb1a8b96b553d2d156f8b5cf440695c04d) (cherry picked from commit c836279fca80fb22ca7ef02acaa5b987fee61123) (cherry picked from commit 4ca0e57c46cf6861ec6f6b6c8e0d430edb3fa5b1) (cherry picked from commit 32e71d5bc09494736866fd78606994f8bf93b31d) (cherry picked from commit 331e81621e2ce822fa1c7658393c2daf7b910db8)
-rw-r--r--src/systemd/src/libsystemd-network/dhcp6-option.c66
1 files changed, 29 insertions, 37 deletions
diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c
index d8812c36fd..d496244370 100644
--- a/src/systemd/src/libsystemd-network/dhcp6-option.c
+++ b/src/systemd/src/libsystemd-network/dhcp6-option.c
@@ -353,6 +353,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
bool first = true;
for (;;) {
+ const char *label;
uint8_t c;
c = optval[pos++];
@@ -360,47 +361,41 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
if (c == 0)
/* End of name */
break;
- else if (c <= 63) {
- const char *label;
-
- /* Literal label */
- label = (const char *)&optval[pos];
- pos += c;
- if (pos >= optlen)
- return -EMSGSIZE;
-
- if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) {
- r = -ENOMEM;
- goto fail;
- }
-
- if (first)
- first = false;
- else
- ret[n++] = '.';
-
- r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
- if (r < 0)
- goto fail;
-
- n += r;
- continue;
- } else {
- r = -EBADMSG;
- goto fail;
- }
- }
+ if (c > 63)
+ return -EBADMSG;
+
+ /* Literal label */
+ label = (const char *)&optval[pos];
+ pos += c;
+ if (pos >= optlen)
+ return -EMSGSIZE;
+
+ if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
+ return -ENOMEM;
+
+ if (first)
+ first = false;
+ else
+ ret[n++] = '.';
- if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
- r = -ENOMEM;
- goto fail;
+ r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
+ if (r < 0)
+ return r;
+
+ n += r;
}
+ if (n == 0)
+ continue;
+
+ if (!GREEDY_REALLOC(ret, allocated, n + 1))
+ return -ENOMEM;
+
ret[n] = 0;
r = strv_extend(&names, ret);
if (r < 0)
- goto fail;
+ return r;
idx++;
}
@@ -409,7 +404,4 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
names = NULL;
return idx;
-
-fail:
- return r;
}