From 7d883dd95e4da1cb9edb2ae753116964ba8975fe Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 29 Oct 2018 14:43:34 +0100 Subject: [PATCH] dhcp: fix out-of-bounds heap write for DHCPv6 with internal plugin (CVE-2018-15688) --- 0001-dhcp-CVE-2018-15688.patch | 299 +++++++++++++++++++++++++++++++++ NetworkManager.spec | 6 +- 2 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 0001-dhcp-CVE-2018-15688.patch diff --git a/0001-dhcp-CVE-2018-15688.patch b/0001-dhcp-CVE-2018-15688.patch new file mode 100644 index 0000000..77b7588 --- /dev/null +++ b/0001-dhcp-CVE-2018-15688.patch @@ -0,0 +1,299 @@ +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 + diff --git a/NetworkManager.spec b/NetworkManager.spec index 9add8b0..31ddd30 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -10,7 +10,7 @@ %global epoch_version 1 %global rpm_version 1.14.4 %global real_version 1.14.4 -%global release_version 1 +%global release_version 2 %global snapshot %{nil} %global git_sha %{nil} @@ -111,6 +111,7 @@ Source3: 20-connectivity-fedora.conf Source4: 20-connectivity-redhat.conf #Patch1: 0001-some.patch +Patch1: 0001-dhcp-CVE-2018-15688.patch Requires(post): systemd Requires(post): /usr/sbin/update-alternatives @@ -969,6 +970,9 @@ fi %changelog +* Mon Oct 29 2018 Thomas Haller - 1:1.14.4-2 +- dhcp: fix out-of-bounds heap write for DHCPv6 with internal plugin (CVE-2018-15688) + * Wed Oct 24 2018 Lubomir Rintel - 1:1.14.4-1 - Update to 1.14.4 release - Temporarily disable the initrd generator (rh #1641832)