summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2011-02-28 02:31:56 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2011-02-28 02:31:56 +0000
commit989c4668410e5f06975ac9cf8b7e3b290eeed732 (patch)
treea76ce4c606084a29523b56f0c8b7869ac4e808e0
parent398536665c473589e9721db24814ccd3e9672a3b (diff)
fix a buffer overflow in the pppoe receive packet handling.
diff from yasuoka@ ok deraadt@
-rw-r--r--usr.sbin/npppd/pppoe/pppoed.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/usr.sbin/npppd/pppoe/pppoed.c b/usr.sbin/npppd/pppoe/pppoed.c
index 6f0962379fc..0c975c87313 100644
--- a/usr.sbin/npppd/pppoe/pppoed.c
+++ b/usr.sbin/npppd/pppoe/pppoed.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pppoed.c,v 1.6 2010/07/02 21:20:57 yasuoka Exp $ */
+/* $OpenBSD: pppoed.c,v 1.7 2011/02/28 02:31:55 dlg Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -28,7 +28,7 @@
/**@file
* This file provides the PPPoE(RFC2516) server(access concentrator)
* implementaion.
- * $Id: pppoed.c,v 1.6 2010/07/02 21:20:57 yasuoka Exp $
+ * $Id: pppoed.c,v 1.7 2011/02/28 02:31:55 dlg Exp $
*/
#include <sys/types.h>
#include <sys/param.h>
@@ -739,6 +739,7 @@ pppoed_input(pppoed_listener *_this, uint8_t shost[ETHER_ADDR_LEN], int is_disc,
int session_id;
slist tag_list;
const char *reason;
+#define tlvspace_remaining() (sizeof(tlvspace) - (p_tlvspace - tlvspace))
reason = "";
p_tlvspace = tlvspace;
@@ -795,6 +796,10 @@ pppoed_input(pppoed_listener *_this, uint8_t shost[ETHER_ADDR_LEN], int is_disc,
"Remaining octet is too short.";
goto fail;
}
+ if (tlvspace_remaining() < 4) {
+ reason = "parsing TAGs reached the buffer size limit.";
+ goto fail;
+ }
tlv = (struct pppoe_tlv *)p_tlvspace;
GETSHORT(tlv->type, pkt);
GETSHORT(tlv->length, pkt);
@@ -804,8 +809,12 @@ pppoed_input(pppoed_listener *_this, uint8_t shost[ETHER_ADDR_LEN], int is_disc,
reason = "tlv list is broken. length is wrong.";
goto fail;
}
+ if (tlvspace_remaining() < tlv->length) {
+ reason = "parsing TAGs reached the buffer size limit.";
+ goto fail;
+ }
if (tlv->length > 0) {
- memcpy(&tlv->value, pkt, tlv->length);
+ memcpy(tlv->value, pkt, tlv->length);
pkt += tlv->length;
lpkt -= tlv->length;
p_tlvspace += tlv->length;