xorl %eax, %eax

CVE-2010-3611: ISC DHCPv6 Remote NULL Pointer Dereference

leave a comment »

A few minutes ago I read this Red Hat’s bugzilla entry. You can also find the official security advisory of ISC DHCP here. John Gibbins is credited for the discovery of this bug and now let’s have a look at it…
First of all, it affects versions 4.0 through 4.2 and can be found at server/dhcpv6.c in the below routine.

/* Find a DHCPv6 packet's shared network from hints in the packet.
 */
static isc_result_t
shared_network_from_packet6(struct shared_network **shared,
                            struct packet *packet)
{
        const struct packet *chk_packet;
        const struct in6_addr *link_addr, *first_link_addr;
        struct iaddr tmp_addr;
        struct subnet *subnet;
        isc_result_t status;
   ...
        /*
         * If there is a relayed link address, find the subnet associated
         * with that, and use that to get the appropriate
         * shared_network.
         */
        if (first_link_addr != NULL) {
   ...
        /*
         * If there is no link address, we will use the interface
         * that this packet came in on to pick the shared_network.
         */
        } else {
                status = shared_network_reference(shared,
                                         packet->interface->shared_network,
                                         MDL);
        }

        return status;
}

As we can read from the function’s comments this is used with DHCPv6 packets to discover packet’s shared network. For better understanding of the vulnerability, here is a snippet of the definition of ‘packet’ structure which resides at includes/dhcpd.h header file.

struct packet {
        struct dhcp_packet *raw;
        int refcnt;
        unsigned packet_length;
        int packet_type;
   ...
        struct interface_info *interface;       /* Interface on which packet
                                                   was received. */
   ...
};

The ‘interface’ member will normally point to the interface that the packet was received. However, as the ISC security advisory informs us:

If the server receives a DHCPv6 packet containing one or more Relay-Forward messages, 
and none of them supply an address in the Relay-Forward link-address field, then the 
server will crash.  This can be used as a single packet crash attack vector.

it will crash under these conditions. This happens because the above ‘interface’ pointer will be pointing to NULL. If we look back to shared_network_from_packet6() we’ll notice that the latter pointer is dereferenced when calling shared_network_reference() routine. That dereference will crash DHCP daemon if ‘interface’ is NULL.
The patch for this vulnerability is:

 	 */
-	} else {
+	} else if (packet->interface != NULL) {
 		status = shared_network_reference(shared,
 					 packet->interface->shared_network,
 					 MDL);
+                if (packet->dhcpv6_container_packet != NULL) {
+			log_info("[L2 Relay] No link address in relay packet "
+				 "assuming L2 relay and using receiving "
+				 "interface");
+                }
+
+	} else {
+		/*
+		 * We shouldn't be able to get here but if there is no link
+		 * address and no interface we don't know where to get the
+		 * pool from log an error and return an error.
+		 */
+		log_error("No interface and no link address " 
+			  "can't determine pool");
+		status = ISC_R_INVALIDARG;
 	}

Which means that a new ‘else if’ clause is defined to handle it after checking that ‘interface’ is not NULL, and some logging code is added to handle with erroneous situations of NULL ‘interface’ pointers. In addition, dhcpv6_relay_forw() that handles the ‘Relay-forw’ message’s encapsulated replies, was patched.

 	enc_packet->client_addr = packet->client_addr;
+	interface_reference(&enc_packet->interface, packet->interface, MDL);
 	enc_packet->dhcpv6_container_packet = packet;

To call interface_reference() and consequently initialize the previously NULL pointer.

Written by xorl

November 16, 2010 at 02:39

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s