summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMariano Lopez <mariano.lopez@linux.intel.com>2016-03-11 08:47:09 (GMT)
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-05-09 07:11:33 (GMT)
commitdad3b97a9a3f6e23873e788ff80c06f8ac7e7140 (patch)
treebddb513c6d166dbb30c7d81699fa64be3c35fb22
parent900d7d6b59c36b2bdbd1c85febec99e80ab54f95 (diff)
downloadpoky-dad3b97a9a3f6e23873e788ff80c06f8ac7e7140.tar.gz
dhcp: CVE-2015-8605
ISC DHCP allows remote attackers to cause a denial of service (application crash) via an invalid length field in a UDP IPv4 packet. (From OE-Core rev: 43f2cfdf63fb70e3c2da0224221dae63b05477df) Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com> Signed-off-by: Joshua Lock <joshua.g.lock@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605.patch101
-rw-r--r--meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605_1.patch131
-rw-r--r--meta/recipes-connectivity/dhcp/dhcp_4.3.1.bb2
3 files changed, 234 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605.patch b/meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605.patch
new file mode 100644
index 0000000..05f1fa9
--- /dev/null
+++ b/meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605.patch
@@ -0,0 +1,101 @@
1Solves CVE-2015-8605 that caused DoS when an invalid length field in IPv4 UDP
2was received by the server.
3
4Upstream-Status: Backport (v4.3.3p1)
5CVE: CVE-2015-8605
6
7From: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=4ce21cb6301d665de01c1a6209e40f5f35072c0c
8
9Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
10
11=======================================================================
12diff --git a/common/packet.c b/common/packet.c
13index b530432..e600e37 100644
14--- a/common/packet.c
15+++ b/common/packet.c
16@@ -220,7 +220,28 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
17 }
18 }
19
20-/* UDP header and IP header decoded together for convenience. */
21+/*!
22+ *
23+ * \brief UDP header and IP header decoded together for convenience.
24+ *
25+ * Attempt to decode the UDP and IP headers and, if necessary, checksum
26+ * the packet.
27+ *
28+ * \param inteface - the interface on which the packet was recevied
29+ * \param buf - a pointer to the buffer for the received packet
30+ * \param bufix - where to start processing the buffer, previous
31+ * routines may have processed parts of the buffer already
32+ * \param from - space to return the address of the packet sender
33+ * \param buflen - remaining length of the buffer, this will have been
34+ * decremented by bufix by the caller
35+ * \param rbuflen - space to return the length of the payload from the udp
36+ * header
37+ * \param csum_ready - indication if the checksum is valid for use
38+ * non-zero indicates the checksum should be validated
39+ *
40+ * \return - the index to the first byte of the udp payload (that is the
41+ * start of the DHCP packet
42+ */
43
44 ssize_t
45 decode_udp_ip_header(struct interface_info *interface,
46@@ -231,7 +252,7 @@ decode_udp_ip_header(struct interface_info *interface,
47 unsigned char *data;
48 struct ip ip;
49 struct udphdr udp;
50- unsigned char *upp, *endbuf;
51+ unsigned char *upp;
52 u_int32_t ip_len, ulen, pkt_len;
53 static unsigned int ip_packets_seen = 0;
54 static unsigned int ip_packets_bad_checksum = 0;
55@@ -241,11 +262,8 @@ decode_udp_ip_header(struct interface_info *interface,
56 static unsigned int udp_packets_length_overflow = 0;
57 unsigned len;
58
59- /* Designate the end of the input buffer for bounds checks. */
60- endbuf = buf + bufix + buflen;
61-
62 /* Assure there is at least an IP header there. */
63- if ((buf + bufix + sizeof(ip)) > endbuf)
64+ if (sizeof(ip) > buflen)
65 return -1;
66
67 /* Copy the IP header into a stack aligned structure for inspection.
68@@ -257,13 +275,17 @@ decode_udp_ip_header(struct interface_info *interface,
69 ip_len = (*upp & 0x0f) << 2;
70 upp += ip_len;
71
72- /* Check the IP packet length. */
73+ /* Check packet lengths are within the buffer:
74+ * first the ip header (ip_len)
75+ * then the packet length from the ip header (pkt_len)
76+ * then the udp header (ip_len + sizeof(udp)
77+ * We are liberal in what we accept, the udp payload should fit within
78+ * pkt_len, but we only check against the full buffer size.
79+ */
80 pkt_len = ntohs(ip.ip_len);
81- if (pkt_len > buflen)
82- return -1;
83-
84- /* Assure after ip_len bytes that there is enough room for a UDP header. */
85- if ((upp + sizeof(udp)) > endbuf)
86+ if ((ip_len > buflen) ||
87+ (pkt_len > buflen) ||
88+ ((ip_len + sizeof(udp)) > buflen))
89 return -1;
90
91 /* Copy the UDP header into a stack aligned structure for inspection. */
92@@ -284,7 +306,8 @@ decode_udp_ip_header(struct interface_info *interface,
93 return -1;
94
95 udp_packets_length_checked++;
96- if ((upp + ulen) > endbuf) {
97+ /* verify that the payload length from the udp packet fits in the buffer */
98+ if ((ip_len + ulen) > buflen) {
99 udp_packets_length_overflow++;
100 if (((udp_packets_length_checked > 4) &&
101 (udp_packets_length_overflow != 0)) &&
diff --git a/meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605_1.patch b/meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605_1.patch
new file mode 100644
index 0000000..aa93c5e
--- /dev/null
+++ b/meta/recipes-connectivity/dhcp/dhcp/CVE-2015-8605_1.patch
@@ -0,0 +1,131 @@
1This patch is needed in order to apply the patch for CVE-2015-8605.
2
3Upstream-Status: Backport (4.3.2+)
4
5From: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=0ce1aa94454ce9b50d592c08d7e0c559d38d3bc5
6
7Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
8---
9From 0ce1aa94454ce9b50d592c08d7e0c559d38d3bc5 Mon Sep 17 00:00:00 2001
10From: Thomas Markwalder <tmark@isc.org>
11Date: Mon, 8 Sep 2014 09:31:32 -0400
12Subject: [PATCH] [master] Corrected error in UDP bad packet logging
13
14 Merges in rt36897
15---
16 common/packet.c | 55 +++++++++++++++++++++++++++++++++++--------------------
17 1 file changed, 35 insertions(+), 20 deletions(-)
18
19diff --git a/common/packet.c b/common/packet.c
20index 45e96e8..7460f3d 100644
21--- a/common/packet.c
22+++ b/common/packet.c
23@@ -3,7 +3,7 @@
24 Packet assembly code, originally contributed by Archie Cobbs. */
25
26 /*
27- * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
28+ * Copyright (c) 2009,2012,2014 by Internet Systems Consortium, Inc. ("ISC")
29 * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC")
30 * Copyright (c) 1996-2003 by Internet Software Consortium
31 *
32@@ -234,12 +234,12 @@ decode_udp_ip_header(struct interface_info *interface,
33 unsigned char *upp, *endbuf;
34 u_int32_t ip_len, ulen, pkt_len;
35 u_int32_t sum, usum;
36- static int ip_packets_seen;
37- static int ip_packets_bad_checksum;
38- static int udp_packets_seen;
39- static int udp_packets_bad_checksum;
40- static int udp_packets_length_checked;
41- static int udp_packets_length_overflow;
42+ static unsigned int ip_packets_seen = 0;
43+ static unsigned int ip_packets_bad_checksum = 0;
44+ static unsigned int udp_packets_seen = 0;
45+ static unsigned int udp_packets_bad_checksum = 0;
46+ static unsigned int udp_packets_length_checked = 0;
47+ static unsigned int udp_packets_length_overflow = 0;
48 unsigned len;
49
50 /* Designate the end of the input buffer for bounds checks. */
51@@ -287,10 +287,10 @@ decode_udp_ip_header(struct interface_info *interface,
52 udp_packets_length_checked++;
53 if ((upp + ulen) > endbuf) {
54 udp_packets_length_overflow++;
55- if ((udp_packets_length_checked > 4) &&
56- ((udp_packets_length_checked /
57- udp_packets_length_overflow) < 2)) {
58- log_info("%d udp packets in %d too long - dropped",
59+ if (((udp_packets_length_checked > 4) &&
60+ (udp_packets_length_overflow != 0)) &&
61+ ((udp_packets_length_checked / udp_packets_length_overflow) < 2)) {
62+ log_info("%u udp packets in %u too long - dropped",
63 udp_packets_length_overflow,
64 udp_packets_length_checked);
65 udp_packets_length_overflow = 0;
66@@ -299,22 +299,31 @@ decode_udp_ip_header(struct interface_info *interface,
67 return -1;
68 }
69
70- if ((ulen < sizeof(udp)) || ((upp + ulen) > endbuf))
71- return -1;
72+ /* If at least 5 with less than 50% bad, start over */
73+ if (udp_packets_length_checked > 4) {
74+ udp_packets_length_overflow = 0;
75+ udp_packets_length_checked = 0;
76+ }
77
78 /* Check the IP header checksum - it should be zero. */
79- ++ip_packets_seen;
80+ ip_packets_seen++;
81 if (wrapsum (checksum (buf + bufix, ip_len, 0))) {
82 ++ip_packets_bad_checksum;
83- if (ip_packets_seen > 4 &&
84- (ip_packets_seen / ip_packets_bad_checksum) < 2) {
85- log_info ("%d bad IP checksums seen in %d packets",
86+ if (((ip_packets_seen > 4) && (ip_packets_bad_checksum != 0)) &&
87+ ((ip_packets_seen / ip_packets_bad_checksum) < 2)) {
88+ log_info ("%u bad IP checksums seen in %u packets",
89 ip_packets_bad_checksum, ip_packets_seen);
90 ip_packets_seen = ip_packets_bad_checksum = 0;
91 }
92 return -1;
93 }
94
95+ /* If at least 5 with less than 50% bad, start over */
96+ if (ip_packets_seen > 4) {
97+ ip_packets_bad_checksum = 0;
98+ ip_packets_seen = 0;
99+ }
100+
101 /* Copy out the IP source address... */
102 memcpy(&from->sin_addr, &ip.ip_src, 4);
103
104@@ -339,15 +348,21 @@ decode_udp_ip_header(struct interface_info *interface,
105 udp_packets_seen++;
106 if (usum && usum != sum) {
107 udp_packets_bad_checksum++;
108- if (udp_packets_seen > 4 &&
109- (udp_packets_seen / udp_packets_bad_checksum) < 2) {
110- log_info ("%d bad udp checksums in %d packets",
111+ if (((udp_packets_seen > 4) && (udp_packets_bad_checksum != 0)) &&
112+ ((udp_packets_seen / udp_packets_bad_checksum) < 2)) {
113+ log_info ("%u bad udp checksums in %u packets",
114 udp_packets_bad_checksum, udp_packets_seen);
115 udp_packets_seen = udp_packets_bad_checksum = 0;
116 }
117 return -1;
118 }
119
120+ /* If at least 5 with less than 50% bad, start over */
121+ if (udp_packets_seen > 4) {
122+ udp_packets_bad_checksum = 0;
123+ udp_packets_seen = 0;
124+ }
125+
126 /* Copy out the port... */
127 memcpy (&from -> sin_port, &udp.uh_sport, sizeof udp.uh_sport);
128
129--
1302.6.2
131
diff --git a/meta/recipes-connectivity/dhcp/dhcp_4.3.1.bb b/meta/recipes-connectivity/dhcp/dhcp_4.3.1.bb
index d4414cc..4616693 100644
--- a/meta/recipes-connectivity/dhcp/dhcp_4.3.1.bb
+++ b/meta/recipes-connectivity/dhcp/dhcp_4.3.1.bb
@@ -6,7 +6,9 @@ SRC_URI += "file://dhcp-3.0.3-dhclient-dbus.patch;striplevel=0 \
6 file://fixsepbuild.patch \ 6 file://fixsepbuild.patch \
7 file://dhclient-script-drop-resolv.conf.dhclient.patch \ 7 file://dhclient-script-drop-resolv.conf.dhclient.patch \
8 file://replace-ifconfig-route.patch \ 8 file://replace-ifconfig-route.patch \
9 file://CVE-2015-8605_1.patch \
9 file://dhcp-xen-checksum.patch \ 10 file://dhcp-xen-checksum.patch \
11 file://CVE-2015-8605.patch \
10 " 12 "
11 13
12SRC_URI[md5sum] = "b3a42ece3c7f2cd2e74a3e12ca881d20" 14SRC_URI[md5sum] = "b3a42ece3c7f2cd2e74a3e12ca881d20"