[pkg-dhcp-commits] [SCM] ISC DHCP packaging for Debian branch, master, updated. debian/4.1.1-P1-16.1-74-gd516495

Michael Gilbert mgilbert at debian.org
Sat Apr 28 20:08:27 UTC 2012


The following commit has been merged in the master branch:
commit 803793aa5e9c84d7e074474b88a8a3bea7fe67b7
Author: Michael Gilbert <mgilbert at debian.org>
Date:   Sat Apr 28 15:59:10 2012 -0400

    Fix cve-2011-4868: error in DDNS handling with IPv6 (closes: #655746)

diff --git a/debian/patches/cve-2011-4868.patch b/debian/patches/cve-2011-4868.patch
new file mode 100644
index 0000000..bc87176
--- /dev/null
+++ b/debian/patches/cve-2011-4868.patch
@@ -0,0 +1,262 @@
+Description: Fix cve-2011-4868: error in DDNS handling with IPv6
+Bug-Debian: http://bugs.debian.org/655746
+Index: isc-dhcp/includes/dhcpd.h
+===================================================================
+--- isc-dhcp.orig/includes/dhcpd.h	2012-04-27 13:33:50.000000000 -0400
++++ isc-dhcp/includes/dhcpd.h	2012-04-28 15:46:28.000000000 -0400
+@@ -1554,6 +1554,7 @@
+ #define DDNS_CLIENT_DID_UPDATE  0x10
+ #define DDNS_EXECUTE_NEXT       0x20
+ #define DDNS_ABORT              0x40
++#define DDNS_ACTIVE_LEASE       0x100
+ 
+ /*
+  * The following two groups are separate and we could reuse
+@@ -1595,7 +1596,7 @@
+ 	int zone_addr_count;
+ 	struct dns_zone *zone;
+ 
+-	int flags;
++	u_int16_t flags;
+ 	TIME timeout;
+ 	int state;
+ 	ddns_action_t cur_func;
+@@ -1947,7 +1948,7 @@
+ /* ddns.c */
+ int ddns_updates(struct packet *, struct lease *, struct lease *,
+ 		 struct iasubopt *, struct iasubopt *, struct option_state *);
+-int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *);
++int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *, isc_boolean_t);
+ #if defined (TRACING)
+ void trace_ddns_init(void);
+ #endif
+Index: isc-dhcp/server/ddns.c
+===================================================================
+--- isc-dhcp.orig/server/ddns.c	2012-04-27 13:33:50.000000000 -0400
++++ isc-dhcp/server/ddns.c	2012-04-28 15:51:44.000000000 -0400
+@@ -123,8 +123,12 @@
+ 	if (ddns_cb == NULL) {
+ 		return(0);
+ 	}
+-	/* assume that we shall update both the A and ptr records */
+-	ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR;
++       /*
++        * Assume that we shall update both the A and ptr records and,
++        * as this is an update, set the active flag 
++        */
++       ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR |
++               DDNS_ACTIVE_LEASE;
+  	
+ 	if (lease != NULL) {
+ 		scope = &(lease->scope);
+@@ -322,7 +326,7 @@
+ 
+ 		/* If desired do the removals */
+ 		if (do_remove != 0) {
+-			(void) ddns_removals(lease, lease6, NULL);
++			(void) ddns_removals(lease, lease6, NULL, ISC_TRUE);
+ 		}
+ 		goto out;
+ 	}
+@@ -524,7 +528,7 @@
+ 	 * the ddns messages.  Currently we don't.
+ 	 */
+ 	if (do_remove) {
+-		rcode1 = ddns_removals(lease, lease6, ddns_cb);
++		rcode1 = ddns_removals(lease, lease6, ddns_cb, ISC_TRUE);
+ 	}
+ 	else {
+ 		ddns_fwd_srv_connector(lease, lease6, scope, ddns_cb,
+@@ -725,6 +729,15 @@
+ 	struct in6_addr        addr;
+ 	struct data_string     lease_dhcid;
+ 	
++	/* 
++	 * If we are processing an expired or released v6 lease
++	 * we don't actually have a scope to update
++  	 */
++	if ((ddns_cb->address.len == 16) &&
++	   ((ddns_cb->flags & DDNS_ACTIVE_LEASE) == 0)) {
++		return (ISC_R_SUCCESS);
++	}
++
+ 	if (inscope != NULL) {
+ 		scope = inscope;
+ 	} else if (ddns_cb->address.len == 4) {
+@@ -1052,6 +1065,15 @@
+ 		 file, line, ddns_cb, ddns_address );
+ #endif
+ 
++	/* 
++	 * If we are processing an expired or released v6 lease
++	 * we don't actually have a scope to update
++	 */
++	if ((ddns_cb->address.len == 16) &&
++	    ((ddns_cb->flags & DDNS_ACTIVE_LEASE) == 0)) {
++		return (ISC_R_SUCCESS);
++	}
++
+ 	if (lease != NULL) {
+ 		safe_lease_update(lease, NULL, ddns_cb, ddns_cb_set, 
+ 				  file, line);
+@@ -1104,7 +1126,7 @@
+ 		     ISC_R_SUCCESS) &&
+ 		    (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != 
+ 		     ISC_R_SUCCESS)) {
+-			inet_ntop(AF_INET6, &lease6->addr, addrbuf,
++			inet_ntop(AF_INET6, &addr, addrbuf,
+ 				  MAX_ADDRESS_STRING_LEN);
+ 			log_error("%s(%d): Pool for lease %s not found.",
+ 				  file, line, addrbuf);
+@@ -1124,7 +1146,7 @@
+ 			find_lease6->ddns_cb = ddns_cb_set;
+ 			iasubopt_dereference(&find_lease6, MDL);
+ 		} else {
+-			inet_ntop(AF_INET6, &lease6->addr, addrbuf,
++			inet_ntop(AF_INET6, &addr, addrbuf,
+ 				  MAX_ADDRESS_STRING_LEN);
+ 			log_error("%s(%d): Lease %s not found within pool.",
+ 				  file, line, addrbuf);
+@@ -1566,12 +1588,18 @@
+  * 0 - badness occurred and we weren't able to do what was wanted
+  * 1 - we were able to do stuff but it's in progress
+  * in both cases any additional block has been passed on to it's handler
++ * 
++ * active == ISC_TRUE if the lease is still active, and FALSE if the lease
++ * is inactive.  This is used to indicate if the lease is inactive or going
++ * to inactive in IPv6 so we can avoid trying to update the lease with
++ * cb pointers and text information.
+  */
+ 
+ int
+ ddns_removals(struct lease    *lease,
+ 	      struct iasubopt *lease6,
+-	      dhcp_ddns_cb_t  *add_ddns_cb)
++	      dhcp_ddns_cb_t  *add_ddns_cb,
++	      isc_boolean_t    active)
+ {
+ 	isc_result_t rcode, execute_add = ISC_R_FAILURE;
+ 	struct binding_scope **scope = NULL;
+@@ -1610,6 +1638,16 @@
+ 	} else
+ 		goto cleanup;
+ 
++	/*
++	 * Set the flag bit if the lease is active, that is it isn't
++	 * expired or released.  This is used in the IPv6 paths to
++	 * determine if we need to update the lease when the response
++	 * from the DNS code is processed.
++	 */
++	if (active == ISC_TRUE) {
++		ddns_cb->flags |= DDNS_ACTIVE_LEASE;
++	}
++
+ 	/* No scope implies that DDNS has not been performed for this lease. */
+ 	if (*scope == NULL)
+ 		goto cleanup;
+Index: isc-dhcp/server/failover.c
+===================================================================
+--- isc-dhcp.orig/server/failover.c	2012-04-27 13:33:50.000000000 -0400
++++ isc-dhcp/server/failover.c	2012-04-28 15:44:55.000000000 -0400
+@@ -5218,7 +5218,7 @@
+ 	 */
+ 	if (msg->binding_status == FTS_ACTIVE &&
+ 	    (chaddr_changed || ident_changed)) {
+-		ddns_removals(lease, NULL, NULL);
++		ddns_removals(lease, NULL, NULL, ISC_FALSE);
+ 
+ 		if (lease->scope != NULL)
+ 			binding_scope_dereference(&lease->scope, MDL);
+Index: isc-dhcp/server/mdb6.c
+===================================================================
+--- isc-dhcp.orig/server/mdb6.c	2012-04-27 13:33:50.000000000 -0400
++++ isc-dhcp/server/mdb6.c	2012-04-28 15:44:55.000000000 -0400
+@@ -1058,7 +1058,7 @@
+ #if defined (NSUPDATE)
+ 		/* Process events upon expiration. */
+ 		if (pool->pool_type != D6O_IA_PD) {
+-			ddns_removals(NULL, lease, NULL);
++			ddns_removals(NULL, lease, NULL, ISC_FALSE);
+ 		}
+ #endif
+ 
+@@ -1466,6 +1466,11 @@
+ 		 * Note that if there are no leases in the pool, 
+ 		 * expire_lease6() will return ISC_R_SUCCESS with 
+ 		 * a NULL lease.
++		 *
++		 * expire_lease6() will call move_lease_to_inactive() which
++		 * calls ddns_removals() do we want that on the standard
++		 * expiration timer or a special 'depref' timer?  Original
++		 * query from DH, moved here by SAR.
+ 		 */
+ 		lease = NULL;
+ 		if (expire_lease6(&lease, pool, cur_time) != ISC_R_SUCCESS) {
+@@ -1475,18 +1480,6 @@
+ 			break;
+ 		}
+ 
+-		/* Look to see if there were ddns updates, and if
+-		 * so, drop them.
+-		 *
+-		 * DH: Do we want to do this on a special 'depref'
+-		 * timer rather than expiration timer?
+-		 */
+-#if defined (NSUPDATE)
+-		if (pool->pool_type != D6O_IA_PD) {
+-			ddns_removals(NULL, lease, NULL);
+-		}
+-#endif
+-
+ 		write_ia(lease->ia);
+ 
+ 		iasubopt_dereference(&lease, MDL);
+Index: isc-dhcp/server/mdb.c
+===================================================================
+--- isc-dhcp.orig/server/mdb.c	2012-04-27 13:33:50.000000000 -0400
++++ isc-dhcp/server/mdb.c	2012-04-28 15:44:55.000000000 -0400
+@@ -1445,7 +1445,7 @@
+ 	      lease -> binding_state == FTS_ACTIVE &&
+ 	      lease -> next_binding_state != FTS_RELEASED))) {
+ #if defined (NSUPDATE)
+-		ddns_removals(lease, NULL, NULL);
++		ddns_removals(lease, NULL, NULL, ISC_FALSE);
+ #endif
+ 		if (lease -> on_expiry) {
+ 			execute_statements ((struct binding_value **)0,
+@@ -1511,7 +1511,7 @@
+ 		 * release message.  This is not true of expiry, where the
+ 		 * peer may have extended the lease.
+ 		 */
+-		ddns_removals(lease, NULL, NULL);
++		ddns_removals(lease, NULL, NULL, ISC_FALSE);
+ #endif
+ 		if (lease -> on_release) {
+ 			execute_statements ((struct binding_value **)0,
+@@ -1680,7 +1680,7 @@
+ 	/* If there are statements to execute when the lease is
+ 	   released, execute them. */
+ #if defined (NSUPDATE)
+-	ddns_removals(lease, NULL, NULL);
++	ddns_removals(lease, NULL, NULL, ISC_FALSE);
+ #endif
+ 	if (lease -> on_release) {
+ 		execute_statements ((struct binding_value **)0,
+@@ -1754,7 +1754,7 @@
+ {
+ 	struct lease *lt = (struct lease *)0;
+ #if defined (NSUPDATE)
+-	ddns_removals(lease, NULL, NULL);
++	ddns_removals(lease, NULL, NULL, ISC_FALSE);
+ #endif
+ 
+ 	if (!lease_copy (&lt, lease, MDL))
+@@ -1786,7 +1786,7 @@
+ {
+ 	struct lease *lt = (struct lease *)0;
+ #if defined (NSUPDATE)
+-	ddns_removals(lease, NULL, NULL);
++	ddns_removals(lease, NULL, NULL, ISC_FALSE);
+ #endif
+ 
+ 	if (!lease_copy (&lt, lease, MDL))
diff --git a/debian/patches/series b/debian/patches/series
index d2ff4ca..f7e4175 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,4 @@ fix_exit_hook_doc_manpage
 no_loopback_checksum
 bind-autoconf
 cve-2011-4539.patch
+cve-2011-4868.patch

-- 
ISC DHCP packaging for Debian



More information about the pkg-dhcp-commits mailing list