Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/dist/dhcp Fix CVS-2011-2748, malformed packets can cause ser...
details: https://anonhg.NetBSD.org/src/rev/aff92b4da499
branches: trunk
changeset: 768376:aff92b4da499
user: christos <christos%NetBSD.org@localhost>
date: Mon Aug 15 21:12:43 2011 +0000
description:
Fix CVS-2011-2748, malformed packets can cause server to crash causing a DoS.
diffstat:
dist/dhcp/common/discover.c | 13 ++++++++++++-
dist/dhcp/common/options.c | 31 +++++++++++++++++++------------
dist/dhcp/server/dhcp.c | 6 +++++-
3 files changed, 36 insertions(+), 14 deletions(-)
diffs (124 lines):
diff -r 69274b0c3194 -r aff92b4da499 dist/dhcp/common/discover.c
--- a/dist/dhcp/common/discover.c Mon Aug 15 21:00:49 2011 +0000
+++ b/dist/dhcp/common/discover.c Mon Aug 15 21:12:43 2011 +0000
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: discover.c,v 1.11 2007/10/31 15:26:51 gdt Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: discover.c,v 1.12 2011/08/15 21:12:43 christos Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -830,6 +830,17 @@
}
if (result == 0)
return ISC_R_UNEXPECTED;
+ /*
+ * 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) {
ifrom.len = 4;
diff -r 69274b0c3194 -r aff92b4da499 dist/dhcp/common/options.c
--- a/dist/dhcp/common/options.c Mon Aug 15 21:00:49 2011 +0000
+++ b/dist/dhcp/common/options.c Mon Aug 15 21:12:43 2011 +0000
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: options.c,v 1.6 2006/05/11 09:29:39 mrg Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: options.c,v 1.7 2011/08/15 21:12:43 christos Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
@@ -499,19 +499,26 @@
honor it. */
if (mms) {
- main_buffer_size = mms - DHCP_FIXED_LEN;
+ if (mms < 576)
+ /* Enforce a minimum packet size... */
+ main_buffer_size = mms - 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;
- /* Enforce a minimum packet size... */
- if (main_buffer_size < (576 - DHCP_FIXED_LEN))
- main_buffer_size = 576 - 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 -r 69274b0c3194 -r aff92b4da499 dist/dhcp/server/dhcp.c
--- a/dist/dhcp/server/dhcp.c Mon Aug 15 21:00:49 2011 +0000
+++ b/dist/dhcp/server/dhcp.c Mon Aug 15 21:12:43 2011 +0000
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.11 2009/07/16 22:44:27 tonnerre Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.12 2011/08/15 21:12:43 christos Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -128,6 +128,7 @@
if (packet -> packet_type == DHCPREQUEST &&
packet -> raw -> ciaddr.s_addr &&
!packet -> raw -> giaddr.s_addr &&
+ packet -> options != NULL &&
(packet -> options -> universe_count < agent_universe.index ||
!packet -> options -> universes [agent_universe.index]))
{
@@ -1379,6 +1380,7 @@
/* If there were agent options in the incoming packet, return
them. */
if (packet -> raw -> giaddr.s_addr &&
+ packet -> options != NULL &&
packet -> options -> universe_count > agent_universe.index &&
packet -> options -> universes [agent_universe.index]) {
option_chain_head_reference
@@ -1536,6 +1538,7 @@
them. Do not return the agent options if they were stashed
on the lease. */
if (packet -> raw -> giaddr.s_addr &&
+ packet -> options != NULL &&
packet -> options -> universe_count > agent_universe.index &&
packet -> options -> universes [agent_universe.index] &&
(state -> options -> universe_count <= agent_universe.index ||
@@ -2179,6 +2182,7 @@
in with the packet, so that we can use them at renewal time when
the packet won't have gone through a relay agent. */
if (packet -> raw -> giaddr.s_addr &&
+ packet -> options != NULL &&
packet -> options -> universe_count > agent_universe.index &&
packet -> options -> universes [agent_universe.index] &&
(state -> options -> universe_count <= agent_universe.index ||
Home |
Main Index |
Thread Index |
Old Index