From 157094abd83f933fad142758a7d177cfa1a347f7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 27 Sep 2018 18:04:59 +0900 Subject: [PATCH 1/6] sd-dhcp-lease: fix memleaks (cherry picked from commit e2975f854831d08a25b4f5eb329b6d04102e115f) --- src/systemd/src/libsystemd-network/sd-dhcp-lease.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c index d2402595c6..cac07d3e5f 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c @@ -279,6 +279,8 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { free(option); } + free(lease->root_path); + free(lease->timezone); free(lease->hostname); free(lease->domainname); free(lease->dns); -- 2.17.1 From 91fb1673d5217aaf1461998fd2675630f5c265f9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 27 Sep 2018 23:48:51 +0900 Subject: [PATCH 2/6] dhcp6: fix buffer size checking (cherry picked from commit cb1bdeaf56852275e6b0dd1fba932bb174767f70) --- src/systemd/src/libsystemd-network/sd-dhcp6-client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c index 8444a750a4..0b261a2cba 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -818,8 +818,8 @@ static int client_parse_message( uint8_t *optval; be32_t iaid_lease; - if (len < offsetof(DHCP6Option, data) || - len < offsetof(DHCP6Option, data) + be16toh(option->len)) + if (len < pos + offsetof(DHCP6Option, data) || + len < pos + offsetof(DHCP6Option, data) + be16toh(option->len)) return -ENOBUFS; optcode = be16toh(option->code); -- 2.17.1 From 0e93fd895daa6f0f578ffa8fc4ed3e0ea85c62e8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 19 Oct 2018 03:44:56 +0900 Subject: [PATCH 3/6] sd-dhcp6: fix argument and error handling of dhcp6_option_parse_status() (cherry picked from commit 91c43f3978fa7c8341550b9ca279e460ba7e74e6) (cherry picked from commit 373cbfc8c6e9591b3c8cc12d58c4b31ac35ab24f) --- src/systemd/src/libsystemd-network/dhcp6-option.c | 10 ++++++---- src/systemd/src/libsystemd-network/sd-dhcp6-client.c | 9 +++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c index ff1cbf13d8..cfddefcb56 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-option.c +++ b/src/systemd/src/libsystemd-network/dhcp6-option.c @@ -465,13 +465,15 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) { case SD_DHCP6_OPTION_STATUS_CODE: - status = dhcp6_option_parse_status(option, optlen); - if (status) { + status = dhcp6_option_parse_status(option, optlen + sizeof(DHCP6Option)); + if (status < 0) { + r = status; + goto error; + } + if (status > 0) { log_dhcp6_client(client, "IA status %d", status); - dhcp6_lease_free_ia(ia); - r = -EINVAL; goto error; } diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c index 0b261a2cba..b694786a77 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -870,13 +870,14 @@ static int client_parse_message( break; case SD_DHCP6_OPTION_STATUS_CODE: - status = dhcp6_option_parse_status(option, optlen); - if (status) { + status = dhcp6_option_parse_status(option, optlen + sizeof(DHCP6Option)); + if (status < 0) + return status; + + if (status > 0) { log_dhcp6_client(client, "%s Status %s", dhcp6_message_type_to_string(message->type), dhcp6_message_status_to_string(status)); - dhcp6_lease_free_ia(&lease->ia); - dhcp6_lease_free_ia(&lease->pd); return -EINVAL; } -- 2.17.1 From f11f5abb1a8b96b553d2d156f8b5cf440695c04d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 19 Oct 2018 03:42:10 +0900 Subject: [PATCH 4/6] 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) --- .../src/libsystemd-network/dhcp6-option.c | 66 ++++++++----------- 1 file 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 cfddefcb56..be5c222372 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-option.c +++ b/src/systemd/src/libsystemd-network/dhcp6-option.c @@ -555,6 +555,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++]; @@ -562,47 +563,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++] = '.'; + + r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX); + if (r < 0) + return r; - if (!GREEDY_REALLOC(ret, allocated, n + 1)) { - r = -ENOMEM; - goto fail; + 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++; } @@ -610,7 +605,4 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char * *str_arr = TAKE_PTR(names); return idx; - -fail: - return r; } -- 2.17.1 From cb77290a696dce924e2a993690634986ac035490 Mon Sep 17 00:00:00 2001 From: Li Song Date: Fri, 19 Oct 2018 13:41:51 -0400 Subject: [PATCH 5/6] sd-dhcp: remove unreachable route after rebinding return NAK (cherry picked from commit cc3981b1272b9ce37e7d734a7b2f42e84acac535) (cherry picked from commit 915c2f675a23b2ae16d292d1ac570706f76b384d) --- src/systemd/src/libsystemd-network/sd-dhcp-client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c index 42707f10d8..9158945372 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -1688,6 +1688,8 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i client->timeout_resend = sd_event_source_unref(client->timeout_resend); + client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED); + r = client_initialize(client); if (r < 0) goto error; -- 2.17.1 From fc230dca139142f409d7bac99dbfabe9b004e2fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 19 Oct 2018 12:12:33 +0200 Subject: [PATCH 6/6] dhcp6: make sure we have enough space for the DHCP6 option header Fixes a vulnerability originally discovered by Felix Wilhelm from Google. CVE-2018-15688 LP: #1795921 https://bugzilla.redhat.com/show_bug.cgi?id=1639067 (cherry picked from commit 4dac5eaba4e419b29c97da38a8b1f82336c2c892) (cherry picked from commit 01ca2053bbea09f35b958c8cc7631e15469acb79) --- src/systemd/src/libsystemd-network/dhcp6-option.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemd/src/libsystemd-network/dhcp6-option.c b/src/systemd/src/libsystemd-network/dhcp6-option.c index be5c222372..22970443d6 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-option.c +++ b/src/systemd/src/libsystemd-network/dhcp6-option.c @@ -105,7 +105,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { return -EINVAL; } - if (*buflen < len) + if (*buflen < offsetof(DHCP6Option, data) + len) return -ENOBUFS; ia_hdr = *buf; -- 2.17.1