[dhcp/f16] 4.2.4-P1: fix for CVE-2012-3570 CVE-2012-3571 and CVE-2012-3954 (#842892)

Tomas Hozza thozza at fedoraproject.org
Wed Jul 25 12:17:54 UTC 2012


commit df341d1152632e523a60fd564cfc31731e025333
Author: Tomas Hozza <thozza at redhat.com>
Date:   Wed Jul 25 14:16:31 2012 +0200

    4.2.4-P1: fix for CVE-2012-3570 CVE-2012-3571 and CVE-2012-3954 (#842892)

 dhcp-4.2.4-CVE-2012-3570-3571-3954.patch |  149 ++++++++++++++++++++++++++++++
 dhcp.spec                                |    9 ++-
 2 files changed, 157 insertions(+), 1 deletions(-)
---
diff --git a/dhcp-4.2.4-CVE-2012-3570-3571-3954.patch b/dhcp-4.2.4-CVE-2012-3570-3571-3954.patch
new file mode 100644
index 0000000..aa34f30
--- /dev/null
+++ b/dhcp-4.2.4-CVE-2012-3570-3571-3954.patch
@@ -0,0 +1,149 @@
+diff -up dhcp-4.2.3-P2/common/options.c.CVE-2012-3570-3571-3954 dhcp-4.2.3-P2/common/options.c
+--- dhcp-4.2.3-P2/common/options.c.CVE-2012-3570-3571-3954	2012-07-25 14:02:05.632045359 +0200
++++ dhcp-4.2.3-P2/common/options.c	2012-07-25 14:04:46.089599642 +0200
+@@ -2406,6 +2406,8 @@ prepare_option_buffer(struct universe *u
+ 
+ 	/* And let go of our references. */
+       cleanup:
++	if (lbp != NULL)
++		buffer_dereference(&lbp, MDL);
+ 	option_dereference(&option, MDL);
+ 
+ 	return 1;
+@@ -3801,11 +3803,13 @@ void do_packet (interface, packet, len,
+ 			data_string_forget (&dp, MDL);
+ 		}
+ 	}
+-		
+-	if (decoded_packet -> packet_type)
+-		dhcp (decoded_packet);
+-	else
+-		bootp (decoded_packet);
++
++	if (validate_packet(decoded_packet) != 0) {
++		if (decoded_packet->packet_type)
++			dhcp(decoded_packet);
++		else
++			bootp(decoded_packet);
++	}
+ 
+ 	/* If the caller kept the packet, they'll have upped the refcnt. */
+ 	packet_dereference (&decoded_packet, MDL);
+@@ -4123,4 +4127,47 @@ add_option(struct option_state *options,
+ 	return 1;
+ }
+ 
++/**
++ *  Checks if received BOOTP/DHCPv4 packet is sane
++ *
++ * @param packet received, decoded packet
++ *
++ * @return 1 if packet is sane, 0 if it is not
++ */
++int validate_packet(struct packet *packet)
++{
++	struct option_cache *oc = NULL;
++
++	oc = lookup_option (&dhcp_universe, packet->options,
++			    DHO_DHCP_CLIENT_IDENTIFIER);
++	if (oc) {
++		/* Let's check if client-identifier is sane */
++		if (oc->data.len == 0) {
++			log_debug("Dropped DHCPv4 packet with zero-length client-id");
++			return (0);
+ 
++		} else if (oc->data.len == 1) {
++			/*
++			 * RFC2132, section 9.14 states that minimum length of client-id
++			 * is 2.  We will allow single-character client-ids for now (for
++			 * backwards compatibility), but warn the user that support for
++			 * this is against the standard.
++			 */
++			log_debug("Accepted DHCPv4 packet with one-character client-id - "
++				"a future version of ISC DHCP will reject this");
++		}
++	} else {
++		/* 
++		 * If hlen is 0 we don't have any identifier, we warn the user
++		 * but continue processing the packet as we can.
++		 */
++		if (packet->raw->hlen == 0) {
++			log_debug("Received DHCPv4 packet without client-id"
++				  " option and empty hlen field.");
++		}
++	}
++
++	/* @todo: Add checks for other received options */
++
++	return (1);
++}
+diff -up dhcp-4.2.3-P2/includes/dhcpd.h.CVE-2012-3570-3571-3954 dhcp-4.2.3-P2/includes/dhcpd.h
+--- dhcp-4.2.3-P2/includes/dhcpd.h.CVE-2012-3570-3571-3954	2012-07-25 14:02:05.651045307 +0200
++++ dhcp-4.2.3-P2/includes/dhcpd.h	2012-07-25 14:07:45.840102184 +0200
+@@ -432,11 +432,17 @@ struct packet {
+ 	isc_boolean_t unicast;
+ };
+ 
+-/* A network interface's MAC address. */
++/*
++ * A network interface's MAC address.
++ * 20 bytes for the hardware address
++ * and 1 byte for the type tag
++ */
++
++#define HARDWARE_ADDR_LEN 20
+ 
+ struct hardware {
+ 	u_int8_t hlen;
+-	u_int8_t hbuf [17];
++	u_int8_t hbuf[HARDWARE_ADDR_LEN + 1];
+ };
+ 
+ #if defined(LDAP_CONFIGURATION)
+@@ -1857,6 +1863,8 @@ void do_packet6(struct interface_info *,
+ 		int, int, const struct iaddr *, isc_boolean_t);
+ int packet6_len_okay(const char *, int);
+ 
++int validate_packet(struct packet *);
++
+ int add_option(struct option_state *options,
+ 	       unsigned int option_num,
+ 	       void *data,
+diff -up dhcp-4.2.3-P2/server/dhcpv6.c.CVE-2012-3570-3571-3954 dhcp-4.2.3-P2/server/dhcpv6.c
+--- dhcp-4.2.3-P2/server/dhcpv6.c.CVE-2012-3570-3571-3954	2012-07-25 14:02:05.653045301 +0200
++++ dhcp-4.2.3-P2/server/dhcpv6.c	2012-07-25 14:11:25.062503597 +0200
+@@ -1285,6 +1285,8 @@ lease_to_client(struct data_string *repl
+ 	struct data_string packet_oro;
+ 	isc_boolean_t no_resources_avail;
+ 
++	memset(&packet_oro, 0, sizeof(packet_oro));
++
+ 	/* Locate the client.  */
+ 	if (shared_network_from_packet6(&reply.shared,
+ 					packet) != ISC_R_SUCCESS)
+@@ -1307,7 +1309,6 @@ lease_to_client(struct data_string *repl
+ 	 * Get the ORO from the packet, if any.
+ 	 */
+ 	oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ORO);
+-	memset(&packet_oro, 0, sizeof(packet_oro));
+ 	if (oc != NULL) {
+ 		if (!evaluate_option_cache(&packet_oro, packet, 
+ 					   NULL, NULL, 
+@@ -1579,6 +1580,8 @@ lease_to_client(struct data_string *repl
+ 		packet_dereference(&reply.packet, MDL);
+ 	if (reply.client_id.data != NULL)
+ 		data_string_forget(&reply.client_id, MDL);
++	if (packet_oro.buffer != NULL)
++		data_string_forget(&packet_oro, MDL);
+ 	reply.renew = reply.rebind = reply.prefer = reply.valid = 0;
+ 	reply.cursor = 0;
+ }
+@@ -6130,7 +6133,7 @@ find_hosts_by_duid_chaddr(struct host_de
+ 		break;
+ 	}
+ 
+-	if (hlen == 0)
++	if ((hlen == 0) || (hlen > HARDWARE_ADDR_LEN)) 
+ 		return 0;
+ 
+ 	/*
diff --git a/dhcp.spec b/dhcp.spec
index 049de05..1e53681 100644
--- a/dhcp.spec
+++ b/dhcp.spec
@@ -19,7 +19,7 @@
 Summary:  Dynamic host configuration protocol software
 Name:     dhcp
 Version:  4.2.3
-Release:  9.%{patchver}%{?dist}
+Release:  10.%{patchver}%{?dist}
 # NEVER CHANGE THE EPOCH on this package.  The previous maintainer (prior to
 # dcantrell maintaining the package) made incorrect use of the epoch and
 # that's why it is at 12 now.  It should have never been used, but it was.
@@ -70,6 +70,7 @@ Patch30:  dhcp-4.2.2-sharedlib.patch
 Patch31:  dhcp-4.2.0-PPP.patch
 Patch32:  dhcp-4.2.3-paranoia.patch
 Patch33:  dhcp-4.2.3-P2-log_perror.patch
+Patch34:  dhcp-4.2.4-CVE-2012-3570-3571-3954.patch
 
 BuildRequires: autoconf
 BuildRequires: automake
@@ -313,6 +314,9 @@ rm bind/bind.tar.gz
 # (Submitted to dhcp-bugs at isc.org - [ISC-Bugs #28049])
 %patch33 -p1 -b .log_perror
 
+# 4.2.4-P1: fix for CVE-2012-3570 CVE-2012-3571 and CVE-2012-3954 (#842892)
+%patch34 -p1 -b .CVE-2012-3570-3571-3954
+
 # Copy in the Fedora/RHEL dhclient script
 %{__install} -p -m 0755 %{SOURCE4} client/scripts/linux
 %{__install} -p -m 0644 %{SOURCE5} .
@@ -646,6 +650,9 @@ fi
 %{_initddir}/dhcrelay
 
 %changelog
+* Wed Jul 25 2012 Tomas Hozza <thozza at redhat.com> - 12:4.2.3-10.P2
+- 4.2.4-P1: fix for CVE-2012-3570 CVE-2012-3571 and CVE-2012-3954 (#842892)
+
 * Mon Jul 09 2012 Tomas Hozza <thozza at redhat.com> - 12:4.2.3-9.P2
 - changed the list of %verify on the leases files (#837474)
 


More information about the scm-commits mailing list