Am 01.11.18 um 21:27 schrieb Adam D. Barratt: >>From a quick look I'd be OK with that, but it seems like the additional > changes should be mentioned somehow in the changelog. I've rewritten the changelog: > network-manager (1.6.2-3+deb9u2) stretch; urgency=medium > > * Cherry-pick various fixes for the sd-network based dhcp=internal plugin > - Make sure we have enough space for the DHCP6 option header. > Fixes out-of-bounds heap write in dhcpv6 option handling. > (CVE-2018-15688, LP: #1795921) > - Remove unreachable route after rebinding return NAK > - Make dhcp6_option_parse_domainname() not store empty domain > - Fix memleaks when releasing a dhcp lease > - Fix an off-by-one error in dhcp6_option_parse_domainname > - Fix assertion starting DHCP client without MAC address > - Fix incorrect clearing of ipv4ll probe conflict counter > > -- Michael Biebl <biebl@debian.org> Fri, 02 Nov 2018 07:13:36 +0100 Full debdiff attached. Please review. Regards, Michael -- Why is it that all of the instruments seeking intelligent life in the universe are pointed away from Earth?
diff --git a/debian/changelog b/debian/changelog index ebb876f17..da4191601 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,18 @@ +network-manager (1.6.2-3+deb9u2) stretch; urgency=medium + + * Cherry-pick various fixes for the sd-network based dhcp=internal plugin + - Make sure we have enough space for the DHCP6 option header. + Fixes out-of-bounds heap write in dhcpv6 option handling. + (CVE-2018-15688, LP: #1795921) + - Remove unreachable route after rebinding return NAK + - Make dhcp6_option_parse_domainname() not store empty domain + - Fix memleaks when releasing a dhcp lease + - Fix an off-by-one error in dhcp6_option_parse_domainname + - Fix assertion starting DHCP client without MAC address + - Fix incorrect clearing of ipv4ll probe conflict counter + + -- Michael Biebl <biebl@debian.org> Fri, 02 Nov 2018 07:13:36 +0100 + network-manager (1.6.2-3+deb9u1) stretch; urgency=medium * libnm: Fix accessing enabled and metered properties. diff --git a/debian/patches/dhcp6-fix-an-off-by-one-error-in-dhcp6_option_parse_domai.patch b/debian/patches/dhcp6-fix-an-off-by-one-error-in-dhcp6_option_parse_domai.patch new file mode 100644 index 000000000..718ecc72c --- /dev/null +++ b/debian/patches/dhcp6-fix-an-off-by-one-error-in-dhcp6_option_parse_domai.patch @@ -0,0 +1,50 @@ +From: Evgeny Vereshchagin <evvers@ya.ru> +Date: Sat, 29 Sep 2018 03:06:10 +0000 +Subject: dhcp6: fix an off-by-one error in dhcp6_option_parse_domainname + +==14==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200055fa9c at pc 0x0000005458f1 bp 0x7ffc78940d90 sp 0x7ffc78940d88 +READ of size 1 at 0x60200055fa9c thread T0 + #0 0x5458f0 in dhcp6_option_parse_domainname /work/build/../../src/systemd/src/libsystemd-network/dhcp6-option.c:555:29 + #1 0x54706e in dhcp6_lease_set_domains /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-lease.c:242:13 + #2 0x53fce0 in client_parse_message /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:984:29 + #3 0x53f3bc in client_receive_advertise /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:1083:13 + #4 0x53d57f in client_receive_message /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:1182:21 + #5 0x7f0f7159deee in source_dispatch /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3042:21 + #6 0x7f0f7159d431 in sd_event_dispatch /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3455:21 + #7 0x7f0f7159ea8d in sd_event_run /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3512:21 + #8 0x531f2b in fuzz_client /work/build/../../src/systemd/src/fuzz/fuzz-dhcp6-client.c:44:9 + #9 0x531bc1 in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-dhcp6-client.c:53:9 + #10 0x57bec8 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:570:15 + #11 0x579d67 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:479:3 + #12 0x57dc92 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:707:19 + #13 0x580ca6 in fuzzer::Fuzzer::Loop(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, fuzzer::fuzzer_allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) /src/libfuzzer/FuzzerLoop.cpp:838:5 + #14 0x55e968 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6 + #15 0x551a1c in main /src/libfuzzer/FuzzerMain.cpp:20:10 + #16 0x7f0f701a082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) + #17 0x41e928 in _start (/out/fuzz-dhcp6-client+0x41e928) + +https://github.com/systemd/systemd/pull/10200 +https://github.com/systemd/systemd/commit/b387d3c1327a3ad2a2509bd3d3491e674392ff21 +(cherry picked from commit 7cb7cffc4962245a32e87017bcf264005c043250) +(cherry picked from commit cd3aacefdd0b91741b7b2e7b5ee5baab210addd9) +(cherry picked from commit 5b140a77bc7b01dc002dbf28a7a2507a27a63d7c) +(cherry picked from commit 0f25f47767794fb179edb9916566a208fbcfcb8f) +(cherry picked from commit c13e43979e10e636e3787bf85a4d56fa5187e70d) +(cherry picked from commit b7b2c8ad3829528eb24dacd91fac9056d731933a) +--- + 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 3a77e34..d8812c3 100644 +--- a/src/systemd/src/libsystemd-network/dhcp6-option.c ++++ b/src/systemd/src/libsystemd-network/dhcp6-option.c +@@ -366,7 +366,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, char * + /* Literal label */ + label = (const char *)&optval[pos]; + pos += c; +- if (pos > optlen) ++ if (pos >= optlen) + return -EMSGSIZE; + + if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) { diff --git a/debian/patches/dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-option.patch b/debian/patches/dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-option.patch new file mode 100644 index 000000000..5e5b0d156 --- /dev/null +++ b/debian/patches/dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-option.patch @@ -0,0 +1,35 @@ +From: Lennart Poettering <lennart@poettering.net> +Date: Fri, 19 Oct 2018 12:12:33 +0200 +Subject: 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) +(cherry picked from commit fc230dca139142f409d7bac99dbfabe9b004e2fb) +(cherry picked from commit cc1e5a7f5731f223d1eb8473fa0eecbedfc0ae5f) +(cherry picked from commit c3221cb0c5b4a2936c198e33b6f7853141991277) +(cherry picked from commit f4f765534191ed3c5d8e78b97333f3fd978a2b63) +(cherry picked from commit 2a25872910606d83f0532d668e73ab4809ee7f90) +--- + 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 d496244..7615cb8 100644 +--- a/src/systemd/src/libsystemd-network/dhcp6-option.c ++++ b/src/systemd/src/libsystemd-network/dhcp6-option.c +@@ -103,7 +103,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; diff --git a/debian/patches/libsystemd-network-ipv4ll-probe-conflict-counter-5361.patch b/debian/patches/libsystemd-network-ipv4ll-probe-conflict-counter-5361.patch new file mode 100644 index 000000000..f279e69f4 --- /dev/null +++ b/debian/patches/libsystemd-network-ipv4ll-probe-conflict-counter-5361.patch @@ -0,0 +1,47 @@ +From: Jason Reeder <jasonreeder@gmail.com> +Date: Thu, 16 Feb 2017 04:14:38 -0600 +Subject: libsystemd-network: ipv4ll probe conflict counter (#5361) + +A bug exists where the conflict counter is cleared +regardless of whether or not the next probe attempt leads to +a successful address acquisition. This causes 'bursts' of +MAX_CONFLICTS probes followed by a delay of +RATE_LIMIT_INTERVAL instead of a single probe each +RATE_LIMIT_INTERVAL when beyond MAX_CONFLICTS. + +The conflict counter should only be cleared after an +address is successfully acquired. This commit achieves that +goal. + +From RFC3927: +A host should maintain a counter of the number of address +conflicts it has experienced in the process of trying to +acquire an address, and if the number of conflicts exceeds +MAX_CONFLICTS then the host MUST limit the rate at which it +probes for new addresses to no more than one new address per +RATE_LIMIT_INTERVAL. This is to prevent catastrophic ARP +storms in pathological failure cases, such as a rogue host +that answers all ARP probes, causing legitimate hosts to go +into an infinite loop attempting to select a usable address. + +Signed-off-by: Jason Reeder <jasonreeder@gmail.com> + +(cherry picked from commit 0cbc024d591e1b1095d90494e0337dabd9ef2e19) +(cherry picked from commit eb8fd9cdfd69028ef22a9d0de32ade9751fcea82) +--- + src/systemd/src/libsystemd-network/sd-ipv4acd.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c +index 913c1ad..3976768 100644 +--- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c ++++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c +@@ -244,8 +244,6 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata) + r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC); + if (r < 0) + goto fail; +- +- acd->n_conflict = 0; + } else { + r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC); + if (r < 0) diff --git a/debian/patches/sd-dhcp-lease-fix-memleaks.patch b/debian/patches/sd-dhcp-lease-fix-memleaks.patch new file mode 100644 index 000000000..a85d5d577 --- /dev/null +++ b/debian/patches/sd-dhcp-lease-fix-memleaks.patch @@ -0,0 +1,27 @@ +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Thu, 27 Sep 2018 18:04:59 +0900 +Subject: sd-dhcp-lease: fix memleaks + +(cherry picked from commit e2975f854831d08a25b4f5eb329b6d04102e115f) +(cherry picked from commit 157094abd83f933fad142758a7d177cfa1a347f7) +(cherry picked from commit 3fd9d11619a5e60d375076fbe13851dd1d3a4a63) +(cherry picked from commit 4439f07841bdddc6878132a993c229df032e8e85) +(cherry picked from commit cbd0609cc482168912c747bad883ba6d434c2a11) +(cherry picked from commit 3a070225b54692da89c801a1dc3df42a11d209a1) +--- + 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 5a3bff2..d92441f 100644 +--- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c ++++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c +@@ -277,6 +277,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); diff --git a/debian/patches/sd-dhcp-remove-unreachable-route-after-rebinding-return-N.patch b/debian/patches/sd-dhcp-remove-unreachable-route-after-rebinding-return-N.patch new file mode 100644 index 000000000..c3e1f5054 --- /dev/null +++ b/debian/patches/sd-dhcp-remove-unreachable-route-after-rebinding-return-N.patch @@ -0,0 +1,28 @@ +From: Li Song <song.li@honeywell.com> +Date: Fri, 19 Oct 2018 13:41:51 -0400 +Subject: sd-dhcp: remove unreachable route after rebinding return NAK + +(cherry picked from commit cc3981b1272b9ce37e7d734a7b2f42e84acac535) +(cherry picked from commit 915c2f675a23b2ae16d292d1ac570706f76b384d) +(cherry picked from commit cb77290a696dce924e2a993690634986ac035490) +(cherry picked from commit f211b140a5861ddedc2424946e3ab07d3b642b5f) +(cherry picked from commit 1cfefbb99ff3c2ab7a0f54829c6f3f787d9e6d77) +(cherry picked from commit f3f5441820d0ecd0ff6861480ace696a6bf34fbd) +(cherry picked from commit 7337cd21dd1e4a285ff1ae9463b42460a64c3107) +--- + 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 7809a81..737b142 100644 +--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c ++++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c +@@ -1571,6 +1571,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; diff --git a/debian/patches/sd-dhcp6-make-dhcp6_option_parse_domainname-not-store-emp.patch b/debian/patches/sd-dhcp6-make-dhcp6_option_parse_domainname-not-store-emp.patch new file mode 100644 index 000000000..3f24eeba7 --- /dev/null +++ b/debian/patches/sd-dhcp6-make-dhcp6_option_parse_domainname-not-store-emp.patch @@ -0,0 +1,115 @@ +From: Yu Watanabe <watanabe.yu+github@gmail.com> +Date: Fri, 19 Oct 2018 03:42:10 +0900 +Subject: 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) +--- + src/systemd/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 d8812c3..d496244 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; + } diff --git a/debian/patches/series b/debian/patches/series index e5e2cccd9..76f05792d 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -21,3 +21,10 @@ device-separately-handle-NMDevice-s-autoconnect-by-user-a.patch device-add-get_autoconnect_allowed-virtual-function.patch device-wifi-block-autoconnect-while-scanning-is-in-progre.patch libnm-client-proxy-_enabled-and-metered-properties-to-the.patch +libsystemd-network-ipv4ll-probe-conflict-counter-5361.patch +systemd-dhcp-fix-assertion-starting-DHCP-client-without-M.patch +dhcp6-fix-an-off-by-one-error-in-dhcp6_option_parse_domai.patch +sd-dhcp-lease-fix-memleaks.patch +sd-dhcp6-make-dhcp6_option_parse_domainname-not-store-emp.patch +sd-dhcp-remove-unreachable-route-after-rebinding-return-N.patch +dhcp6-make-sure-we-have-enough-space-for-the-DHCP6-option.patch diff --git a/debian/patches/systemd-dhcp-fix-assertion-starting-DHCP-client-without-M.patch b/debian/patches/systemd-dhcp-fix-assertion-starting-DHCP-client-without-M.patch new file mode 100644 index 000000000..7b254810b --- /dev/null +++ b/debian/patches/systemd-dhcp-fix-assertion-starting-DHCP-client-without-M.patch @@ -0,0 +1,45 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Mon, 10 Sep 2018 15:22:28 +0200 +Subject: systemd/dhcp: fix assertion starting DHCP client without MAC address + +An assertion in dhcp_network_bind_raw_socket() is triggered when +starting an sd_dhcp_client without setting setting a MAC address +first. + + - sd_dhcp_client_start() + - client_start() + - client_start_delayed() + - dhcp_network_bind_raw_socket() + +In that case, the arp-type and MAC address is still unset. Note that +dhcp_network_bind_raw_socket() already checks for a valid arp-type +and MAC address below, so we should just gracefully return -EINVAL. + +Maybe sd_dhcp_client_start() should fail earlier when starting without +MAC address. But the failure here will be correctly propagated and +the start aborted. + +See-also: https://github.com/systemd/systemd/pull/10054 +(cherry picked from commit 34af574d5810ab2b0d6d354cbc28135cde4a55b1) +(cherry picked from commit 0a797bdc2a592385a21e7ed918c08ef54a346d99) +(cherry picked from commit f37ed84ca495ee212b1e82b9c5a5682c4acfebcd) +(cherry picked from commit 1031b2bb5c97bd48ff93f85537b3f5ce0f6f64bf) +(cherry picked from commit 4ca49f52fae5c7841f873bc0a01d654dc19c2152) +(cherry picked from commit 59941b21247c53091f303b58106f9b7a446835f1) +--- + src/systemd/src/libsystemd-network/dhcp-network.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/systemd/src/libsystemd-network/dhcp-network.c b/src/systemd/src/libsystemd-network/dhcp-network.c +index 7ad0ec3..f0b1b0a 100644 +--- a/src/systemd/src/libsystemd-network/dhcp-network.c ++++ b/src/systemd/src/libsystemd-network/dhcp-network.c +@@ -142,8 +142,6 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, + const uint8_t *bcast_addr = NULL; + uint8_t dhcp_hlen = 0; + +- assert_return(mac_addr_len > 0, -EINVAL); +- + if (arp_type == ARPHRD_ETHER) { + assert_return(mac_addr_len == ETH_ALEN, -EINVAL); + memcpy(ð_mac, mac_addr, ETH_ALEN);
Attachment:
signature.asc
Description: OpenPGP digital signature