tcpdump/0015-Report-a-too-long-unreachable-destination-list.patch
Michal Sekletar a41ce5f646 Fix for CVE-2014-8769
Resolves: #1165162
2014-11-21 15:23:48 +01:00

82 lines
2.4 KiB
Diff

From 3f5693a2bb783b1caa2a308e64ee34d167f36f05 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Wed, 12 Nov 2014 01:09:27 -0800
Subject: [PATCH 4/4] Report a too-long unreachable destination list.
Running out of packet length before running out of unreachable
destinations is an error; report it as such.
Don't worry about leftover data past the end of the list of unreachable
destinations.
---
print-aodv.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index 9b3523a..ef27eee 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -277,14 +277,15 @@ aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length)
ap->rerr_dc, length));
dp = (struct rerr_unreach *)(dat + sizeof(*ap));
i = length - sizeof(*ap);
- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp);
- ++dp, --dc, i -= sizeof(*dp)) {
+ for (dc = ap->rerr_dc; dc != 0; dc--) {
ND_TCHECK(*dp);
+ if (i < sizeof(*dp))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
+ dp++;
+ i -= sizeof(*dp);
}
- if ((i % sizeof(*dp)) != 0)
- goto trunc;
return;
trunc:
@@ -386,14 +387,15 @@ aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length)
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6 *)(void *)(ap + 1);
i = length - sizeof(*ap);
- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
- ++dp6, --dc, i -= sizeof(*dp6)) {
+ for (dc = ap->rerr_dc; dc != 0; dc--) {
ND_TCHECK(*dp6);
+ if (i < sizeof(*dp6))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
+ dp6++;
+ i -= sizeof(*dp6);
}
- if ((i % sizeof(*dp6)) != 0)
- goto trunc;
return;
trunc:
@@ -498,14 +500,15 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int leng
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1);
i = length - sizeof(*ap);
- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
- ++dp6, --dc, i -= sizeof(*dp6)) {
+ for (dc = ap->rerr_dc; dc != 0; dc--) {
ND_TCHECK(*dp6);
+ if (i < sizeof(*dp6))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
+ dp6++;
+ i -= sizeof(*dp6);
}
- if ((i % sizeof(*dp6)) != 0)
- goto trunc;
return;
trunc:
--
1.8.3.1