dhcp: fix out-of-bounds heap write for DHCPv6 with internal plugin (CVE-2018-15688)
This commit is contained in:
parent
b0b96b60c2
commit
c7129b6cc7
|
@ -0,0 +1,327 @@
|
|||
From aff13dd42efe390d72ad7a9605b06e44fefddfeb Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Haller <thaller@redhat.com>
|
||||
Date: Mon, 10 Sep 2018 15:22:28 +0200
|
||||
Subject: [PATCH 1/6] 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)
|
||||
---
|
||||
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 7ad0ec375..f0b1b0a22 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);
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
From 141c3fe8f083449e2a9d223a4f8995ad89ca0501 Mon Sep 17 00:00:00 2001
|
||||
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||
Date: Sat, 29 Sep 2018 03:06:10 +0000
|
||||
Subject: [PATCH 2/6] 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)
|
||||
---
|
||||
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 3a77e34d5..d8812c36f 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)) {
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
From c854e0c2eea17c9d2f49d0c416a25b35186de577 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 27 Sep 2018 18:04:59 +0900
|
||||
Subject: [PATCH 3/6] 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)
|
||||
---
|
||||
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 5a3bff2f7..d92441fc5 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);
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
From 4f6f76aa79bb63c6fea356d702e80754e8291728 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
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)
|
||||
(cherry picked from commit f11f5abb1a8b96b553d2d156f8b5cf440695c04d)
|
||||
(cherry picked from commit c836279fca80fb22ca7ef02acaa5b987fee61123)
|
||||
(cherry picked from commit 4ca0e57c46cf6861ec6f6b6c8e0d430edb3fa5b1)
|
||||
(cherry picked from commit 32e71d5bc09494736866fd78606994f8bf93b31d)
|
||||
---
|
||||
.../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 d8812c36f..d49624437 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;
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
From 017d77c8c6c88fd4cfa1a2f8a2ac03b9a491f314 Mon Sep 17 00:00:00 2001
|
||||
From: Li Song <song.li@honeywell.com>
|
||||
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)
|
||||
(cherry picked from commit cb77290a696dce924e2a993690634986ac035490)
|
||||
(cherry picked from commit f211b140a5861ddedc2424946e3ab07d3b642b5f)
|
||||
(cherry picked from commit 1cfefbb99ff3c2ab7a0f54829c6f3f787d9e6d77)
|
||||
(cherry picked from commit f3f5441820d0ecd0ff6861480ace696a6bf34fbd)
|
||||
---
|
||||
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 17393e206..c9623a448 100644
|
||||
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
|
||||
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
|
||||
@@ -1580,6 +1580,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 35b634d535c8f151bcb6add9630305121349802c Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
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)
|
||||
(cherry picked from commit fc230dca139142f409d7bac99dbfabe9b004e2fb)
|
||||
(cherry picked from commit cc1e5a7f5731f223d1eb8473fa0eecbedfc0ae5f)
|
||||
(cherry picked from commit c3221cb0c5b4a2936c198e33b6f7853141991277)
|
||||
(cherry picked from commit f4f765534191ed3c5d8e78b97333f3fd978a2b63)
|
||||
---
|
||||
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 d49624437..7615cb80e 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;
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
%global epoch_version 1
|
||||
%global rpm_version 1.8.8
|
||||
%global real_version 1.8.8
|
||||
%global release_version 1
|
||||
%global release_version 2
|
||||
%global snapshot %{nil}
|
||||
%global git_sha %{nil}
|
||||
|
||||
|
@ -85,6 +85,7 @@ Source2: 00-server.conf
|
|||
Source3: 20-connectivity-fedora.conf
|
||||
|
||||
#Patch1: 0001-some.patch
|
||||
Patch1: 0001-dhcp-CVE-2018-15688.patch
|
||||
|
||||
Requires(post): systemd
|
||||
Requires(preun): systemd
|
||||
|
@ -340,6 +341,7 @@ by nm-connection-editor and nm-applet in a non-graphical environment.
|
|||
%setup -q -n NetworkManager-%{real_version}
|
||||
|
||||
#%patch1 -p1
|
||||
%patch1 -p1
|
||||
|
||||
%build
|
||||
%if %{with regen_docs}
|
||||
|
@ -669,6 +671,9 @@ fi
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Oct 29 2018 Thomas Haller <thaller@redhat.com> - 1:1.8.8-2
|
||||
- dhcp: fix out-of-bounds heap write for DHCPv6 with internal plugin (CVE-2018-15688)
|
||||
|
||||
* Sat Jun 16 2018 Thomas Haller <thaller@redhat.com> - 1:1.8.8-1
|
||||
- Update to 1.8.8
|
||||
- device: fix crash during reapply of connection settings
|
||||
|
|
Loading…
Reference in New Issue