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 50403cccee)
(cherry picked from commit f11f5abb1a)
This commit is contained in:
Yu Watanabe 2018-10-19 03:42:10 +09:00 committed by Thomas Haller
parent 6ea13fc825
commit c836279fca

View file

@ -555,6 +555,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
bool first = true; bool first = true;
for (;;) { for (;;) {
const char *label;
uint8_t c; uint8_t c;
c = optval[pos++]; c = optval[pos++];
@ -562,47 +563,41 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
if (c == 0) if (c == 0)
/* End of name */ /* End of name */
break; break;
else if (c <= 63) { if (c > 63)
const char *label; return -EBADMSG;
/* Literal label */ /* Literal label */
label = (const char *)&optval[pos]; label = (const char *)&optval[pos];
pos += c; pos += c;
if (pos >= optlen) if (pos >= optlen)
return -EMSGSIZE; return -EMSGSIZE;
if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) { if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
r = -ENOMEM; return -ENOMEM;
goto fail;
}
if (first) if (first)
first = false; first = false;
else else
ret[n++] = '.'; ret[n++] = '.';
r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX); r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
if (r < 0) if (r < 0)
goto fail; return r;
n += r; n += r;
continue;
} else {
r = -EBADMSG;
goto fail;
}
} }
if (!GREEDY_REALLOC(ret, allocated, n + 1)) { if (n == 0)
r = -ENOMEM; continue;
goto fail;
} if (!GREEDY_REALLOC(ret, allocated, n + 1))
return -ENOMEM;
ret[n] = 0; ret[n] = 0;
r = strv_extend(&names, ret); r = strv_extend(&names, ret);
if (r < 0) if (r < 0)
goto fail; return r;
idx++; idx++;
} }
@ -610,7 +605,4 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char *
*str_arr = TAKE_PTR(names); *str_arr = TAKE_PTR(names);
return idx; return idx;
fail:
return r;
} }