diff -up dhcp-3.0.5/client/dhclient.c.CVE-2011-2748-2749 dhcp-3.0.5/client/dhclient.c --- dhcp-3.0.5/client/dhclient.c.CVE-2011-2748-2749 2011-08-10 19:28:46.000000000 +0200 +++ dhcp-3.0.5/client/dhclient.c 2011-08-10 19:30:12.000000000 +0200 @@ -3281,10 +3281,11 @@ void client_option_envadd (struct option if (dhcp_option_ev_name (name, sizeof name, oc->option)) { const char *value; + size_t length; value = pretty_print_option(oc->option, data.data, data.len, 0, 0); - size_t length = strlen(value); + length = strlen(value); if (check_option_values(oc->option->universe, oc->option->code, diff -up dhcp-3.0.5/common/discover.c.CVE-2011-2748-2749 dhcp-3.0.5/common/discover.c --- dhcp-3.0.5/common/discover.c.CVE-2011-2748-2749 2011-08-10 19:14:23.000000000 +0200 +++ dhcp-3.0.5/common/discover.c 2011-08-10 19:14:23.000000000 +0200 @@ -897,12 +897,16 @@ isc_result_t got_one (h) if (result == 0) return ISC_R_UNEXPECTED; - /* If we didn't at least get the fixed portion of the BOOTP - packet, drop the packet. We're allowing packets with no - sname or filename, because we're aware of at least one - client that sends such packets, but this definitely falls - into the category of being forgiving. */ - if (result < DHCP_FIXED_NON_UDP - DHCP_SNAME_LEN - DHCP_FILE_LEN) + /* + * If we didn't at least get the fixed portion of the BOOTP + * packet, drop the packet. + * Previously we allowed packets with no sname or filename + * as we were aware of at least one client that did. But + * a bug caused short packets to not work and nobody has + * complained, it seems rational to tighten up that + * restriction. + */ + if (result < DHCP_FIXED_NON_UDP) return ISC_R_UNEXPECTED; if (bootp_packet_handler) { diff -up dhcp-3.0.5/common/options.c.CVE-2011-2748-2749 dhcp-3.0.5/common/options.c --- dhcp-3.0.5/common/options.c.CVE-2011-2748-2749 2011-08-10 19:14:23.000000000 +0200 +++ dhcp-3.0.5/common/options.c 2011-08-10 19:14:23.000000000 +0200 @@ -490,26 +490,36 @@ int cons_options (inpacket, outpacket, l data_string_forget (&ds, MDL); } - /* If the client has provided a maximum DHCP message size, - use that; otherwise, if it's BOOTP, only 64 bytes; otherwise - use up to the minimum IP MTU size (576 bytes). */ - /* XXX if a BOOTP client specifies a max message size, we will - honor it. */ - + /* + * If the client has provided a maximum DHCP message size, + * use that, up to the MTU limit. Otherwise, if it's BOOTP, + * only 64 bytes; otherwise use up to the minimum IP MTU size + * (576 bytes). + * + * XXX if a BOOTP client specifies a max message size, we will + * honor it. + */ if (mms) { - main_buffer_size = mms - DHCP_FIXED_LEN; - - /* Enforce a minimum packet size... */ - if (main_buffer_size < (576 - DHCP_FIXED_LEN)) + if (mms < 576) + /* Enforce minimum packet size, per RFC 2132 */ main_buffer_size = 576 - DHCP_FIXED_LEN; + else if (mms > 1500) + /* + * TODO: Packets longer than 1500 bytes really + * should be allowed, but it requires upstream + * changes to the way the packet is allocated. For + * now, we forbid them. They won't be needed very + * often anyway. + */ + main_buffer_size = 1500 - DHCP_FIXED_LEN; + else + main_buffer_size = mms - DHCP_FIXED_LEN; + } else if (bootpp) { - if (inpacket) { - main_buffer_size = - inpacket -> packet_length - DHCP_FIXED_LEN; - if (main_buffer_size < 64) - main_buffer_size = 64; - } else - main_buffer_size = 64; + main_buffer_size = 64; + if (inpacket != NULL && + (inpacket->packet_length >= 64 + DHCP_FIXED_NON_UDP)) + main_buffer_size = inpacket->packet_length - DHCP_FIXED_NON_UDP; } else main_buffer_size = 576 - DHCP_FIXED_LEN; diff -up dhcp-3.0.5/server/dhcp.c.CVE-2011-2748-2749 dhcp-3.0.5/server/dhcp.c --- dhcp-3.0.5/server/dhcp.c.CVE-2011-2748-2749 2011-08-10 19:14:23.000000000 +0200 +++ dhcp-3.0.5/server/dhcp.c 2011-08-10 19:14:23.000000000 +0200 @@ -1555,6 +1555,7 @@ void ack_lease (packet, lease, offer, wh * by the user into the new state, not just give up. */ if (!packet->agent_options_stashed && + (packet->options != NULL) && packet->options->universe_count > agent_universe.index && packet->options->universes[agent_universe.index] != NULL && (state->options->universe_count <= agent_universe.index || @@ -2211,6 +2212,7 @@ void ack_lease (packet, lease, offer, wh * giaddr. */ if (!packet->agent_options_stashed && + (packet->options != NULL) && packet->options->universe_count > agent_universe.index && packet->options->universes[agent_universe.index] != NULL) { oc = lookup_option (&server_universe, state -> options,