summaryrefslogtreecommitdiff
path: root/net/cdp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/cdp.c')
-rw-r--r--net/cdp.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/net/cdp.c b/net/cdp.c
index 6e404981d4a..300b3d5c409 100644
--- a/net/cdp.c
+++ b/net/cdp.c
@@ -276,7 +276,13 @@ void cdp_receive(const uchar *pkt, unsigned len)
ss = (const ushort *)pkt;
type = ntohs(ss[0]);
tlen = ntohs(ss[1]);
- if (tlen > len)
+ /*
+ * tlen includes the 4-byte TLV header, so it must be at
+ * least 4. Without this check a crafted tlen < 4 makes the
+ * "tlen -= 4" below underflow (tlen is a ushort), and a tlen
+ * of 0 also fails to advance pkt/len, hanging the loop.
+ */
+ if (tlen < 4 || tlen > len)
goto pkt_short;
pkt += tlen;