[pkg-dhcp-commits] [SCM] ISC DHCP packaging for Debian branch, master, updated. debian/4.2.2.dfsg.1-5-11-g37538e1

Michael Gilbert mgilbert at debian.org
Fri Sep 14 09:01:16 UTC 2012


The following commit has been merged in the master branch:
commit 9331aab6f2904747f6b40316506106c2a85413f3
Author: Michael Gilbert <mgilbert at debian.org>
Date:   Fri Sep 14 00:56:04 2012 -0400

    Fix multiple security issues

diff --git a/debian/patches/cve-2012-3570.patch b/debian/patches/cve-2012-3570.patch
new file mode 100644
index 0000000..ea3c0d6
--- /dev/null
+++ b/debian/patches/cve-2012-3570.patch
@@ -0,0 +1,35 @@
+diff -ur dhcp-4.2.4/includes/dhcpd.h dhcp-4.2.4-P1/includes/dhcpd.h
+--- dhcp-4.2.4/includes/dhcpd.h	2012-05-15 17:07:41.000000000 -0400
++++ dhcp-4.2.4-P1/includes/dhcpd.h	2012-07-13 02:18:05.000000000 -0400
+@@ -432,11 +432,17 @@
+ 	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[21];
++	u_int8_t hbuf[HARDWARE_ADDR_LEN + 1];
+ };
+ 
+ #if defined(LDAP_CONFIGURATION)
+diff -ur dhcp-4.2.4/server/dhcpv6.c dhcp-4.2.4-P1/server/dhcpv6.c
+--- dhcp-4.2.4/server/dhcpv6.c	2012-05-15 17:07:41.000000000 -0400
++++ dhcp-4.2.4-P1/server/dhcpv6.c	2012-07-13 02:18:05.000000000 -0400
+@@ -6037,7 +6040,7 @@
+ 		break;
+ 	}
+ 
+-	if (hlen == 0)
++	if ((hlen == 0) || (hlen > HARDWARE_ADDR_LEN)) 
+ 		return 0;
+ 
+ 	/*
diff --git a/debian/patches/cve-2012-3571.patch b/debian/patches/cve-2012-3571.patch
new file mode 100644
index 0000000..17a6ae6
--- /dev/null
+++ b/debian/patches/cve-2012-3571.patch
@@ -0,0 +1,82 @@
+--- isc-dhcp.orig/common/options.c	2012-09-14 00:36:38.448193613 -0400
++++ isc-dhcp/common/options.c	2012-09-14 00:44:00.681338059 -0400
+@@ -3754,11 +3754,13 @@
+ 			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);
+@@ -4078,4 +4080,47 @@
+ 	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);
++}
+Index: isc-dhcp/includes/dhcpd.h
+===================================================================
+--- isc-dhcp.orig/includes/dhcpd.h	2012-09-14 00:43:50.493773011 -0400
++++ isc-dhcp/includes/dhcpd.h	2012-09-14 00:44:00.681338059 -0400
+@@ -1859,6 +1859,8 @@
+ 		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 --git a/debian/patches/cve-2012-3954.patch b/debian/patches/cve-2012-3954.patch
new file mode 100644
index 0000000..ac28a5a
--- /dev/null
+++ b/debian/patches/cve-2012-3954.patch
@@ -0,0 +1,41 @@
+diff -ur dhcp-4.2.4/common/options.c dhcp-4.2.4-P1/common/options.c
+--- dhcp-4.2.4/common/options.c	2012-03-19 20:31:53.000000000 -0400
++++ dhcp-4.2.4-P1/common/options.c	2012-07-13 02:18:05.000000000 -0400
+@@ -2359,6 +2359,8 @@
+ 
+ 	/* And let go of our references. */
+       cleanup:
++	if (lbp != NULL)
++		buffer_dereference(&lbp, MDL);
+ 	option_dereference(&option, MDL);
+ 
+ 	return status;
+diff -ur dhcp-4.2.4/server/dhcpv6.c dhcp-4.2.4-P1/server/dhcpv6.c
+--- dhcp-4.2.4/server/dhcpv6.c	2012-05-15 17:07:41.000000000 -0400
++++ dhcp-4.2.4-P1/server/dhcpv6.c	2012-07-13 02:18:05.000000000 -0400
+@@ -1254,6 +1254,8 @@
+ 	isc_boolean_t no_resources_avail = ISC_FALSE;
+ #endif
+ 
++	memset(&packet_oro, 0, sizeof(packet_oro));
++
+ 	/* Locate the client.  */
+ 	if (shared_network_from_packet6(&reply.shared,
+ 					packet) != ISC_R_SUCCESS)
+@@ -1276,7 +1278,6 @@
+ 	 * 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, 
+@@ -1519,6 +1520,8 @@
+ 		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;
+ }
diff --git a/debian/patches/cve-2012-3955.patch b/debian/patches/cve-2012-3955.patch
new file mode 100644
index 0000000..1f2743d
--- /dev/null
+++ b/debian/patches/cve-2012-3955.patch
@@ -0,0 +1,115 @@
+diff -ur dhcp-4.2.4-P1/server/dhcpv6.c dhcp-4.2.4-P2/server/dhcpv6.c
+--- dhcp-4.2.4-P1/server/dhcpv6.c	2012-07-13 02:18:05.000000000 -0400
++++ dhcp-4.2.4-P2/server/dhcpv6.c	2012-08-27 22:13:22.000000000 -0400
+@@ -1837,9 +1837,6 @@
+ 			ia_reference(&tmp->ia, reply->ia, MDL);
+ 
+ 			/* Commit 'hard' bindings. */
+-			tmp->hard_lifetime_end_time =
+-				tmp->soft_lifetime_end_time;
+-			tmp->soft_lifetime_end_time = 0;
+ 			renew_lease6(tmp->ipv6_pool, tmp);
+ 			schedule_lease_timeout(tmp->ipv6_pool);
+ 
+@@ -2498,9 +2495,6 @@
+ 			ia_reference(&tmp->ia, reply->ia, MDL);
+ 
+ 			/* Commit 'hard' bindings. */
+-			tmp->hard_lifetime_end_time =
+-				tmp->soft_lifetime_end_time;
+-			tmp->soft_lifetime_end_time = 0;
+ 			renew_lease6(tmp->ipv6_pool, tmp);
+ 			schedule_lease_timeout(tmp->ipv6_pool);
+ 
+@@ -3370,9 +3364,6 @@
+ 			ia_reference(&tmp->ia, reply->ia, MDL);
+ 
+ 			/* Commit 'hard' bindings. */
+-			tmp->hard_lifetime_end_time =
+-				tmp->soft_lifetime_end_time;
+-			tmp->soft_lifetime_end_time = 0;
+ 			renew_lease6(tmp->ipv6_pool, tmp);
+ 			schedule_lease_timeout(tmp->ipv6_pool);
+ 		}
+diff -ur dhcp-4.2.4-P1/server/mdb6.c dhcp-4.2.4-P2/server/mdb6.c
+--- dhcp-4.2.4-P1/server/mdb6.c	2012-07-13 02:17:54.000000000 -0400
++++ dhcp-4.2.4-P2/server/mdb6.c	2012-08-27 22:13:22.000000000 -0400
+@@ -1235,29 +1238,49 @@
+ 	return insert_result;
+ }
+ 
+-/*
+- * Renew an lease in the pool.
++/*!
++ * \brief Renew a lease in the pool.
++ *
++ * The hard_lifetime_end_time of the lease should be set to
++ * the current expiration time.
++ * The soft_lifetime_end_time of the lease should be set to
++ * the desired expiration time.
++ *
++ * This routine will compare the two and call the correct
++ * heap routine to move the lease.  If the lease is active
++ * and the new expiration time is greater (the normal case)
++ * then we call isc_heap_decreased() as a larger time is a
++ * lower priority.  If the new expiration time is less then
++ * we call isc_heap_increased().
++ *
++ * If the lease is abandoned then it will be on the active list
++ * and we will always call isc_heap_increased() as the previous
++ * expiration would have been all 1s (as close as we can get
++ * to infinite).
++ *
++ * If the lease is moving to active we call that routine
++ * which will move it from the inactive list to the active list.
+  *
+- * To do this, first set the new hard_lifetime_end_time for the resource,
+- * and then invoke renew_lease6() on it.
++ * \param pool a pool the lease belongs to
++ * \param lease the lease to be renewed
+  *
+- * WARNING: lease times must only be extended, never reduced!!!
++ * \return result of the renew operation (ISC_R_SUCCESS if successful,
++           ISC_R_NOMEMORY when run out of memory)
+  */
+ isc_result_t
+ renew_lease6(struct ipv6_pool *pool, struct iasubopt *lease) {
+-	/*
+-	 * If we're already active, then we can just move our expiration
+-	 * time down the heap. 
+-	 *
+-	 * If we're abandoned then we are already on the active list
+-	 * but we need to retag the lease and move our expiration
+-	 * from infinite to the current value
+-	 *
+-	 * Otherwise, we have to move from the inactive heap to the 
+-	 * active heap.
+-	 */
++	time_t old_end_time = lease->hard_lifetime_end_time;
++	lease->hard_lifetime_end_time = lease->soft_lifetime_end_time;
++	lease->soft_lifetime_end_time = 0;
++
+ 	if (lease->state == FTS_ACTIVE) {
+-		isc_heap_decreased(pool->active_timeouts, lease->heap_index);
++		if (old_end_time <= lease->hard_lifetime_end_time) {
++			isc_heap_decreased(pool->active_timeouts,
++					   lease->heap_index);
++		} else {
++			isc_heap_increased(pool->active_timeouts,
++					   lease->heap_index);
++		}
+ 		return ISC_R_SUCCESS;
+ 	} else if (lease->state == FTS_ABANDONED) {
+ 		char tmp_addr[INET6_ADDRSTRLEN];
+@@ -1920,9 +1943,8 @@
+ /*
+  * Renew all leases in an IA from all pools.
+  *
+- * The new hard_lifetime_end_time should be updated for the addresses/prefixes.
+- *
+- * WARNING: lease times must only be extended, never reduced!!!
++ * The new lifetime should be in the soft_lifetime_end_time
++ * and will be moved to hard_lifetime_end_time by renew_lease6.
+  */
+ isc_result_t 
+ renew_leases(struct ia_xx *ia) {
diff --git a/debian/patches/series b/debian/patches/series
index 930e1f1..517d7ab 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,7 @@
 dhclient-script-exit-status
 fix_exit_hook_doc_manpage
 no_loopback_checksum
+cve-2012-3570.patch
+cve-2012-3571.patch
+cve-2012-3954.patch
+cve-2012-3955.patch

-- 
ISC DHCP packaging for Debian



More information about the pkg-dhcp-commits mailing list