Accepting request 284472 from home:vitezslav_cizek:branches:network:utilities

- fix CVE-2014-8767 (bnc#905870)
  * denial of service in verbose mode using malformed OLSR payload
  * added tcpdump-CVE-2014-8767.patch
- fix CVE-2014-8768 (bnc#905871)
  * denial of service in verbose mode using malformed Geonet payload
  * added tcpdump-CVE-2014-8768.patch
- fix CVE-2014-8769 (bnc#905872)
  * unreliable output using malformed AOVD payload
  * added tcpdump-CVE-2014-8769.patch
  * added 0001-Clean-up-error-message-printing.patch

OBS-URL: https://build.opensuse.org/request/show/284472
OBS-URL: https://build.opensuse.org/package/show/network:utilities/tcpdump?expand=0&rev=23
This commit is contained in:
Lars Vogdt 2015-02-10 09:23:34 +00:00 committed by Git OBS Bridge
parent fe36004f92
commit b56a2c3b3f
6 changed files with 1255 additions and 1 deletions

View File

@ -0,0 +1,190 @@
From 3e8a443c3671baa37ae7870f08fb9b4bf386fd24 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 18:37:35 -0800
Subject: [PATCH] Clean up error message printing.
Have "struct aodv_rerr" just be the header, not including the actual
destinations.
Simplify the logic somewhat, and make it similar in the print routines
for the three types of error messages.
---
print-aodv.c | 88 +++++++++++++++++++++++++++++++-----------------------------
1 file changed, 46 insertions(+), 42 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index da5b169..da26473 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -146,13 +146,6 @@ struct aodv_rerr {
uint8_t rerr_flags; /* various flags */
uint8_t rerr_zero0; /* reserved, set to zero */
uint8_t rerr_dc; /* destination count */
- union {
- struct rerr_unreach dest[1];
-#ifdef INET6
- struct rerr_unreach6 dest6[1];
- struct rerr_unreach6_draft_01 dest6_draft_01[1];
-#endif
- } r;
};
#define RERR_NODELETE 0x80 /* don't delete the link */
@@ -284,32 +277,29 @@ static void
aodv_rerr(netdissect_options *ndo,
const struct aodv_rerr *ap, const u_char *dat, u_int length)
{
- u_int i;
- const struct rerr_unreach *dp = NULL;
- int n, trunc;
+ u_int i, dc;
+ const struct rerr_unreach *dp;
if (ndo->ndo_snapend < dat) {
ND_PRINT((ndo, " [|aodv]"));
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < offsetof(struct aodv_rerr, r)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rerr]"));
return;
}
- i -= offsetof(struct aodv_rerr, r);
- dp = &ap->r.dest[0];
- n = ap->rerr_dc * sizeof(ap->r.dest[0]);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
- trunc = n - (i/sizeof(ap->r.dest[0]));
- for (; i >= sizeof(ap->r.dest[0]);
- ++dp, i -= sizeof(ap->r.dest[0])) {
+ dp = (struct rerr_unreach *)(void *)(ap + 1);
+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp);
+ ++dp, --dc, i -= sizeof(*dp)) {
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
}
- if (trunc)
+ if ((i % sizeof(*dp)) != 0)
ND_PRINT((ndo, "[|rerr]"));
}
@@ -397,29 +387,36 @@ aodv_v6_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap, u_int length)
+ const struct aodv_rerr *ap, const u_char *dat, u_int length)
#else
aodv_v6_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, const u_char *dat, u_int length)
#endif
{
#ifdef INET6
- const struct rerr_unreach6 *dp6 = NULL;
- int i, j, n, trunc;
+ u_int i, dc;
+ const struct rerr_unreach6 *dp6;
- i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->r.dest6[0]);
- dp6 = &ap->r.dest6[0];
- n = ap->rerr_dc * j;
+ if (ndo->ndo_snapend < dat) {
+ ND_PRINT((ndo, " [|aodv]"));
+ return;
+ }
+ i = min(length, (u_int)(ndo->ndo_snapend - dat));
+ if (i < sizeof(*ap)) {
+ ND_PRINT((ndo, " [|rerr]"));
+ return;
+ }
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
- trunc = n - (i/j);
- for (; i -= j >= 0; ++dp6) {
+ dp6 = (struct rerr_unreach6 *)(void *)(ap + 1);
+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
+ ++dp6, --dc, i -= sizeof(*dp6)) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
}
- if (trunc)
+ if ((i % sizeof(*dp6)) != 0)
ND_PRINT((ndo, "[|rerr]"));
#else
ND_PRINT((ndo, " rerr %u", length));
@@ -510,29 +507,36 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap, u_int length)
+ const struct aodv_rerr *ap, const u_char *dat, u_int length)
#else
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, const u_char *dat, u_int length)
#endif
{
#ifdef INET6
- const struct rerr_unreach6_draft_01 *dp6 = NULL;
- int i, j, n, trunc;
+ u_int i, dc;
+ const struct rerr_unreach6_draft_01 *dp6;
- i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->r.dest6_draft_01[0]);
- dp6 = &ap->r.dest6_draft_01[0];
- n = ap->rerr_dc * j;
+ if (ndo->ndo_snapend < dat) {
+ ND_PRINT((ndo, " [|aodv]"));
+ return;
+ }
+ i = min(length, (u_int)(ndo->ndo_snapend - dat));
+ if (i < sizeof(*ap)) {
+ ND_PRINT((ndo, " [|rerr]"));
+ return;
+ }
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
- trunc = n - (i/j);
- for (; i -= j >= 0; ++dp6) {
+ dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1);
+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
+ ++dp6, --dc, i -= sizeof(*dp6)) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
}
- if (trunc)
+ if ((i % sizeof(*dp6)) != 0)
ND_PRINT((ndo, "[|rerr]"));
#else
ND_PRINT((ndo, " rerr %u", length));
@@ -571,7 +575,7 @@ aodv_print(netdissect_options *ndo,
case AODV_RERR:
if (is_ip6)
- aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, length);
+ aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
else
aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
break;
@@ -589,7 +593,7 @@ aodv_print(netdissect_options *ndo,
break;
case AODV_V6_DRAFT_01_RERR:
- aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, length);
+ aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
break;
case AODV_V6_DRAFT_01_RREP_ACK:
--
2.1.2

183
tcpdump-CVE-2014-8767.patch Normal file
View File

@ -0,0 +1,183 @@
From 4038f83ebf654804829b258dde5e0a508c1c2003 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 16:49:39 -0800
Subject: [PATCH 2/3] Do more bounds checking and length checking.
Don't run past the end of the captured data, and don't run past the end
of the packet (i.e., don't make the length variable go negative).
Also, stop dissecting if the message length isn't valid.
---
print-olsr.c | 56 +++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 43 insertions(+), 13 deletions(-)
diff --git a/print-olsr.c b/print-olsr.c
index 6fa0d76..6d2d65f 100644
--- a/print-olsr.c
+++ b/print-olsr.c
@@ -178,7 +178,7 @@ struct olsr_lq_neighbor6 {
/*
* print a neighbor list with LQ extensions.
*/
-static void
+static int
olsr_print_lq_neighbor4(netdissect_options *ndo,
const u_char *msg_data, u_int hello_len)
{
@@ -187,6 +187,8 @@ olsr_print_lq_neighbor4(netdissect_options *ndo,
while (hello_len >= sizeof(struct olsr_lq_neighbor4)) {
lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data;
+ if (!ND_TTEST(*lq_neighbor))
+ return (-1);
ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%"
", neighbor-link-quality %.2lf%%",
@@ -197,10 +199,11 @@ olsr_print_lq_neighbor4(netdissect_options *ndo,
msg_data += sizeof(struct olsr_lq_neighbor4);
hello_len -= sizeof(struct olsr_lq_neighbor4);
}
+ return (0);
}
#if INET6
-static void
+static int
olsr_print_lq_neighbor6(netdissect_options *ndo,
const u_char *msg_data, u_int hello_len)
{
@@ -209,6 +212,8 @@ olsr_print_lq_neighbor6(netdissect_options *ndo,
while (hello_len >= sizeof(struct olsr_lq_neighbor6)) {
lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data;
+ if (!ND_TTEST(*lq_neighbor))
+ return (-1);
ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%"
", neighbor-link-quality %.2lf%%",
@@ -219,13 +224,14 @@ olsr_print_lq_neighbor6(netdissect_options *ndo,
msg_data += sizeof(struct olsr_lq_neighbor6);
hello_len -= sizeof(struct olsr_lq_neighbor6);
}
+ return (0);
}
#endif /* INET6 */
/*
* print a neighbor list.
*/
-static void
+static int
olsr_print_neighbor(netdissect_options *ndo,
const u_char *msg_data, u_int hello_len)
{
@@ -236,6 +242,8 @@ olsr_print_neighbor(netdissect_options *ndo,
while (hello_len >= sizeof(struct in_addr)) {
+ if (!ND_TTEST2(*msg_data, sizeof(struct in_addr)))
+ return (-1);
/* print 4 neighbors per line */
ND_PRINT((ndo, "%s%s", ipaddr_string(ndo, msg_data),
@@ -244,6 +252,7 @@ olsr_print_neighbor(netdissect_options *ndo,
msg_data += sizeof(struct in_addr);
hello_len -= sizeof(struct in_addr);
}
+ return (0);
}
@@ -326,6 +335,9 @@ olsr_print(netdissect_options *ndo,
ME_TO_DOUBLE(msgptr.v6->vtime),
EXTRACT_16BITS(msgptr.v6->msg_seq),
msg_len, (msg_len_valid == 0) ? " (invalid)" : ""));
+ if (!msg_len_valid) {
+ return;
+ }
msg_tlen = msg_len - sizeof(struct olsr_msg6);
msg_data = tptr + sizeof(struct olsr_msg6);
@@ -354,6 +366,9 @@ olsr_print(netdissect_options *ndo,
ME_TO_DOUBLE(msgptr.v4->vtime),
EXTRACT_16BITS(msgptr.v4->msg_seq),
msg_len, (msg_len_valid == 0) ? " (invalid)" : ""));
+ if (!msg_len_valid) {
+ return;
+ }
msg_tlen = msg_len - sizeof(struct olsr_msg4);
msg_data = tptr + sizeof(struct olsr_msg4);
@@ -362,6 +377,8 @@ olsr_print(netdissect_options *ndo,
switch (msg_type) {
case OLSR_HELLO_MSG:
case OLSR_HELLO_LQ_MSG:
+ if (msg_tlen < sizeof(struct olsr_hello))
+ goto trunc;
ND_TCHECK2(*msg_data, sizeof(struct olsr_hello));
ptr.hello = (struct olsr_hello *)msg_data;
@@ -401,15 +418,21 @@ olsr_print(netdissect_options *ndo,
msg_tlen -= sizeof(struct olsr_hello_link);
hello_len -= sizeof(struct olsr_hello_link);
+ ND_TCHECK2(*msg_data, hello_len);
if (msg_type == OLSR_HELLO_MSG) {
- olsr_print_neighbor(ndo, msg_data, hello_len);
+ if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1)
+ goto trunc;
} else {
#if INET6
- if (is_ipv6)
- olsr_print_lq_neighbor6(ndo, msg_data, hello_len);
- else
+ if (is_ipv6) {
+ if (olsr_print_lq_neighbor6(ndo, msg_data, hello_len) == -1)
+ goto trunc;
+ } else
#endif
- olsr_print_lq_neighbor4(ndo, msg_data, hello_len);
+ {
+ if (olsr_print_lq_neighbor4(ndo, msg_data, hello_len) == -1)
+ goto trunc;
+ }
}
msg_data += hello_len;
@@ -419,6 +442,8 @@ olsr_print(netdissect_options *ndo,
case OLSR_TC_MSG:
case OLSR_TC_LQ_MSG:
+ if (msg_tlen < sizeof(struct olsr_tc))
+ goto trunc;
ND_TCHECK2(*msg_data, sizeof(struct olsr_tc));
ptr.tc = (struct olsr_tc *)msg_data;
@@ -428,14 +453,19 @@ olsr_print(netdissect_options *ndo,
msg_tlen -= sizeof(struct olsr_tc);
if (msg_type == OLSR_TC_MSG) {
- olsr_print_neighbor(ndo, msg_data, msg_tlen);
+ if (olsr_print_neighbor(ndo, msg_data, msg_tlen) == -1)
+ goto trunc;
} else {
#if INET6
- if (is_ipv6)
- olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen);
- else
+ if (is_ipv6) {
+ if (olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen) == -1)
+ goto trunc;
+ } else
#endif
- olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen);
+ {
+ if (olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen) == -1)
+ goto trunc;
+ }
}
break;
--
2.1.2

343
tcpdump-CVE-2014-8768.patch Normal file
View File

@ -0,0 +1,343 @@
From 9255c9b05b0a04b8d89739b3efcb9f393a617fe9 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 15:51:54 -0800
Subject: [PATCH 1/3] Do bounds checking and length checking.
Don't run past the end of the captured data, and don't run past the end
of the packet (i.e., don't make the length variable go negative).
---
print-geonet.c | 270 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 151 insertions(+), 119 deletions(-)
diff --git a/print-geonet.c b/print-geonet.c
index d902066..edfb7f2 100644
--- a/print-geonet.c
+++ b/print-geonet.c
@@ -56,16 +56,12 @@ static const struct tok msg_type_values[] = {
static void
print_btp_body(netdissect_options *ndo,
- const u_char *bp, u_int length)
+ const u_char *bp)
{
int version;
int msg_type;
const char *msg_type_str;
- if (length <= 2) {
- return;
- }
-
/* Assuming ItsDpuHeader */
version = bp[0];
msg_type = bp[1];
@@ -83,7 +79,7 @@ print_btp(netdissect_options *ndo,
ND_PRINT((ndo, "; BTP Dst:%u Src:%u", dest, src));
}
-static void
+static int
print_long_pos_vector(netdissect_options *ndo,
const u_char *bp)
{
@@ -91,10 +87,13 @@ print_long_pos_vector(netdissect_options *ndo,
ND_PRINT((ndo, "GN_ADDR:%s ", linkaddr_string (ndo, bp, 0, GEONET_ADDR_LEN)));
+ if (!ND_TTEST2(*(bp+12), 8))
+ return (-1);
lat = EXTRACT_32BITS(bp+12);
ND_PRINT((ndo, "lat:%d ", lat));
lon = EXTRACT_32BITS(bp+16);
ND_PRINT((ndo, "lon:%d", lon));
+ return (0);
}
@@ -105,137 +104,170 @@ print_long_pos_vector(netdissect_options *ndo,
void
geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length)
{
+ int version;
+ int next_hdr;
+ int hdr_type;
+ int hdr_subtype;
+ uint16_t payload_length;
+ int hop_limit;
+ const char *next_hdr_txt = "Unknown";
+ const char *hdr_type_txt = "Unknown";
+ int hdr_size = -1;
+
ND_PRINT((ndo, "GeoNet src:%s; ", etheraddr_string(ndo, eth+6)));
- if (length >= 36) {
- /* Process Common Header */
- int version = bp[0] >> 4;
- int next_hdr = bp[0] & 0x0f;
- int hdr_type = bp[1] >> 4;
- int hdr_subtype = bp[1] & 0x0f;
- uint16_t payload_length = EXTRACT_16BITS(bp+4);
- int hop_limit = bp[7];
- const char *next_hdr_txt = "Unknown";
- const char *hdr_type_txt = "Unknown";
- int hdr_size = -1;
+ /* Process Common Header */
+ if (length < 36)
+ goto malformed;
+
+ ND_TCHECK2(*bp, 7);
+ version = bp[0] >> 4;
+ next_hdr = bp[0] & 0x0f;
+ hdr_type = bp[1] >> 4;
+ hdr_subtype = bp[1] & 0x0f;
+ payload_length = EXTRACT_16BITS(bp+4);
+ hop_limit = bp[7];
- switch (next_hdr) {
- case 0: next_hdr_txt = "Any"; break;
- case 1: next_hdr_txt = "BTP-A"; break;
- case 2: next_hdr_txt = "BTP-B"; break;
- case 3: next_hdr_txt = "IPv6"; break;
- }
+ switch (next_hdr) {
+ case 0: next_hdr_txt = "Any"; break;
+ case 1: next_hdr_txt = "BTP-A"; break;
+ case 2: next_hdr_txt = "BTP-B"; break;
+ case 3: next_hdr_txt = "IPv6"; break;
+ }
- switch (hdr_type) {
- case 0: hdr_type_txt = "Any"; break;
- case 1: hdr_type_txt = "Beacon"; break;
- case 2: hdr_type_txt = "GeoUnicast"; break;
- case 3: switch (hdr_subtype) {
- case 0: hdr_type_txt = "GeoAnycastCircle"; break;
- case 1: hdr_type_txt = "GeoAnycastRect"; break;
- case 2: hdr_type_txt = "GeoAnycastElipse"; break;
- }
- break;
- case 4: switch (hdr_subtype) {
- case 0: hdr_type_txt = "GeoBroadcastCircle"; break;
- case 1: hdr_type_txt = "GeoBroadcastRect"; break;
- case 2: hdr_type_txt = "GeoBroadcastElipse"; break;
- }
- break;
- case 5: switch (hdr_subtype) {
- case 0: hdr_type_txt = "TopoScopeBcast-SH"; break;
- case 1: hdr_type_txt = "TopoScopeBcast-MH"; break;
- }
- break;
- case 6: switch (hdr_subtype) {
- case 0: hdr_type_txt = "LocService-Request"; break;
- case 1: hdr_type_txt = "LocService-Reply"; break;
- }
- break;
- }
+ switch (hdr_type) {
+ case 0: hdr_type_txt = "Any"; break;
+ case 1: hdr_type_txt = "Beacon"; break;
+ case 2: hdr_type_txt = "GeoUnicast"; break;
+ case 3: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "GeoAnycastCircle"; break;
+ case 1: hdr_type_txt = "GeoAnycastRect"; break;
+ case 2: hdr_type_txt = "GeoAnycastElipse"; break;
+ }
+ break;
+ case 4: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "GeoBroadcastCircle"; break;
+ case 1: hdr_type_txt = "GeoBroadcastRect"; break;
+ case 2: hdr_type_txt = "GeoBroadcastElipse"; break;
+ }
+ break;
+ case 5: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "TopoScopeBcast-SH"; break;
+ case 1: hdr_type_txt = "TopoScopeBcast-MH"; break;
+ }
+ break;
+ case 6: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "LocService-Request"; break;
+ case 1: hdr_type_txt = "LocService-Reply"; break;
+ }
+ break;
+ }
+
+ ND_PRINT((ndo, "v:%d ", version));
+ ND_PRINT((ndo, "NH:%d-%s ", next_hdr, next_hdr_txt));
+ ND_PRINT((ndo, "HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt));
+ ND_PRINT((ndo, "HopLim:%d ", hop_limit));
+ ND_PRINT((ndo, "Payload:%d ", payload_length));
+ if (print_long_pos_vector(ndo, bp + 8) == -1)
+ goto trunc;
- ND_PRINT((ndo, "v:%d ", version));
- ND_PRINT((ndo, "NH:%d-%s ", next_hdr, next_hdr_txt));
- ND_PRINT((ndo, "HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt));
- ND_PRINT((ndo, "HopLim:%d ", hop_limit));
- ND_PRINT((ndo, "Payload:%d ", payload_length));
- print_long_pos_vector(ndo, bp + 8);
+ /* Skip Common Header */
+ length -= 36;
+ bp += 36;
- /* Skip Common Header */
- length -= 36;
- bp += 36;
+ /* Process Extended Headers */
+ switch (hdr_type) {
+ case 0: /* Any */
+ hdr_size = 0;
+ break;
+ case 1: /* Beacon */
+ hdr_size = 0;
+ break;
+ case 2: /* GeoUnicast */
+ break;
+ case 3: switch (hdr_subtype) {
+ case 0: /* GeoAnycastCircle */
+ break;
+ case 1: /* GeoAnycastRect */
+ break;
+ case 2: /* GeoAnycastElipse */
+ break;
+ }
+ break;
+ case 4: switch (hdr_subtype) {
+ case 0: /* GeoBroadcastCircle */
+ break;
+ case 1: /* GeoBroadcastRect */
+ break;
+ case 2: /* GeoBroadcastElipse */
+ break;
+ }
+ break;
+ case 5: switch (hdr_subtype) {
+ case 0: /* TopoScopeBcast-SH */
+ hdr_size = 0;
+ break;
+ case 1: /* TopoScopeBcast-MH */
+ hdr_size = 68 - 36;
+ break;
+ }
+ break;
+ case 6: switch (hdr_subtype) {
+ case 0: /* LocService-Request */
+ break;
+ case 1: /* LocService-Reply */
+ break;
+ }
+ break;
+ }
- /* Process Extended Headers */
- switch (hdr_type) {
+ /* Skip Extended headers */
+ if (hdr_size >= 0) {
+ if (length < (u_int)hdr_size)
+ goto malformed;
+ ND_TCHECK2(*bp, hdr_size);
+ length -= hdr_size;
+ bp += hdr_size;
+ switch (next_hdr) {
case 0: /* Any */
- hdr_size = 0;
- break;
- case 1: /* Beacon */
- hdr_size = 0;
- break;
- case 2: /* GeoUnicast */
break;
- case 3: switch (hdr_subtype) {
- case 0: /* GeoAnycastCircle */
- break;
- case 1: /* GeoAnycastRect */
- break;
- case 2: /* GeoAnycastElipse */
- break;
+ case 1:
+ case 2: /* BTP A/B */
+ if (length < 4)
+ goto malformed;
+ ND_TCHECK2(*bp, 4);
+ print_btp(ndo, bp);
+ length -= 4;
+ bp += 4;
+ if (length >= 2) {
+ /*
+ * XXX - did print_btp_body()
+ * return if length < 2
+ * because this is optional,
+ * or was that just not
+ * reporting genuine errors?
+ */
+ ND_TCHECK2(*bp, 2);
+ print_btp_body(ndo, bp);
}
break;
- case 4: switch (hdr_subtype) {
- case 0: /* GeoBroadcastCircle */
- break;
- case 1: /* GeoBroadcastRect */
- break;
- case 2: /* GeoBroadcastElipse */
- break;
- }
- break;
- case 5: switch (hdr_subtype) {
- case 0: /* TopoScopeBcast-SH */
- hdr_size = 0;
- break;
- case 1: /* TopoScopeBcast-MH */
- hdr_size = 68 - 36;
- break;
- }
- break;
- case 6: switch (hdr_subtype) {
- case 0: /* LocService-Request */
- break;
- case 1: /* LocService-Reply */
- break;
- }
+ case 3: /* IPv6 */
break;
}
-
- /* Skip Extended headers */
- if (hdr_size >= 0) {
- length -= hdr_size;
- bp += hdr_size;
- switch (next_hdr) {
- case 0: /* Any */
- break;
- case 1:
- case 2: /* BTP A/B */
- print_btp(ndo, bp);
- length -= 4;
- bp += 4;
- print_btp_body(ndo, bp, length);
- break;
- case 3: /* IPv6 */
- break;
- }
- }
- } else {
- ND_PRINT((ndo, "Malformed (small) "));
}
/* Print user data part */
if (ndo->ndo_vflag)
ND_DEFAULTPRINT(bp, length);
+ return;
+
+malformed:
+ ND_PRINT((ndo, " Malformed (small) "));
+ /* XXX - print the remaining data as hex? */
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|geonet]"));
}
--
2.1.2

516
tcpdump-CVE-2014-8769.patch Normal file
View File

@ -0,0 +1,516 @@
From ab4e52b94aac6cb729a5a695aa612d5ebda2ec3a Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 17:24:12 -0800
Subject: [PATCH 3/3] Add initial bounds check, get rid of union aodv.
Fetch the type field without using a structure, and check to make sure
it's not past the end of the packet.
Pass to each dissection routine a pointer to the appropriate message
type structure, rather than a pointer to a union of all the message type
structures.
---
print-aodv.c | 274 ++++++++++++++++++++++++++++-------------------------------
1 file changed, 130 insertions(+), 144 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index 093e174..da5b169 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -163,19 +163,6 @@ struct aodv_rrep_ack {
uint8_t ra_zero0;
};
-union aodv {
- struct aodv_rreq rreq;
- struct aodv_rrep rrep;
- struct aodv_rerr rerr;
- struct aodv_rrep_ack rrep_ack;
-#ifdef INET6
- struct aodv_rreq6 rreq6;
- struct aodv_rreq6_draft_01 rreq6_draft_01;
- struct aodv_rrep6 rrep6;
- struct aodv_rrep6_draft_01 rrep6_draft_01;
-#endif
-};
-
#define AODV_RREQ 1 /* route request */
#define AODV_RREP 2 /* route response */
#define AODV_RERR 3 /* error report */
@@ -232,7 +219,7 @@ aodv_extension(netdissect_options *ndo,
static void
aodv_rreq(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rreq *ap, const u_char *dat, u_int length)
{
u_int i;
@@ -241,31 +228,31 @@ aodv_rreq(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rreq)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rreq]"));
return;
}
- i -= sizeof(ap->rreq);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
- ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "",
- ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "",
- ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "",
- ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "",
- ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
- ap->rreq.rreq_hops,
- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id),
- ipaddr_string(ndo, &ap->rreq.rreq_da),
- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds),
- ipaddr_string(ndo, &ap->rreq.rreq_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os)));
+ ap->rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id),
+ ipaddr_string(ndo, &ap->rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
+ ipaddr_string(ndo, &ap->rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rreq + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
}
static void
aodv_rrep(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rrep *ap, const u_char *dat, u_int length)
{
u_int i;
@@ -274,28 +261,28 @@ aodv_rrep(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rrep)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rrep]"));
return;
}
- i -= sizeof(ap->rrep);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
- ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "",
- ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ",
- ap->rrep.rrep_ps & RREP_PREFIX_MASK,
- ap->rrep.rrep_hops,
- ipaddr_string(ndo, &ap->rrep.rrep_da),
- (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds),
- ipaddr_string(ndo, &ap->rrep.rrep_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life)));
+ ap->rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep_hops,
+ ipaddr_string(ndo, &ap->rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
+ ipaddr_string(ndo, &ap->rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rrep + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
}
static void
aodv_rerr(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rerr *ap, const u_char *dat, u_int length)
{
u_int i;
const struct rerr_unreach *dp = NULL;
@@ -311,14 +298,14 @@ aodv_rerr(netdissect_options *ndo,
return;
}
i -= offsetof(struct aodv_rerr, r);
- dp = &ap->rerr.r.dest[0];
- n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]);
+ dp = &ap->r.dest[0];
+ n = ap->rerr_dc * sizeof(ap->r.dest[0]);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
- ap->rerr.rerr_dc, length));
- trunc = n - (i/sizeof(ap->rerr.r.dest[0]));
- for (; i >= sizeof(ap->rerr.r.dest[0]);
- ++dp, i -= sizeof(ap->rerr.r.dest[0])) {
+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr_dc, length));
+ trunc = n - (i/sizeof(ap->r.dest[0]));
+ for (; i >= sizeof(ap->r.dest[0]);
+ ++dp, i -= sizeof(ap->r.dest[0])) {
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
}
@@ -329,10 +316,10 @@ aodv_rerr(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rreq(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rreq6 *ap, const u_char *dat, u_int length)
#else
aodv_v6_rreq(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_, u_int length)
+ const struct aodv_rreq6 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -343,26 +330,26 @@ aodv_v6_rreq(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rreq6)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rreq6]"));
return;
}
- i -= sizeof(ap->rreq6);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
- ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "",
- ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "",
- ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "",
- ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "",
- ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
- ap->rreq6.rreq_hops,
- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id),
- ip6addr_string(ndo, &ap->rreq6.rreq_da),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds),
- ip6addr_string(ndo, &ap->rreq6.rreq_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os)));
+ ap->rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id),
+ ip6addr_string(ndo, &ap->rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
+ ip6addr_string(ndo, &ap->rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rreq6 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " v6 rreq %u", length));
#endif
@@ -371,10 +358,10 @@ aodv_v6_rreq(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rrep(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rrep6 *ap, const u_char *dat, u_int length)
#else
aodv_v6_rrep(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_, u_int length)
+ const struct aodv_rrep6 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -385,23 +372,23 @@ aodv_v6_rrep(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rrep6)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rrep6]"));
return;
}
- i -= sizeof(ap->rrep6);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
- ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "",
- ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ",
- ap->rrep6.rrep_ps & RREP_PREFIX_MASK,
- ap->rrep6.rrep_hops,
- ip6addr_string(ndo, &ap->rrep6.rrep_da),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds),
- ip6addr_string(ndo, &ap->rrep6.rrep_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life)));
+ ap->rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep_hops,
+ ip6addr_string(ndo, &ap->rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
+ ip6addr_string(ndo, &ap->rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rrep6 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " rrep %u", length));
#endif
@@ -410,10 +397,10 @@ aodv_v6_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rerr(netdissect_options *ndo,
- const union aodv *ap, u_int length)
+ const struct aodv_rerr *ap, u_int length)
#else
aodv_v6_rerr(netdissect_options *ndo,
- const union aodv *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, u_int length)
#endif
{
#ifdef INET6
@@ -421,12 +408,12 @@ aodv_v6_rerr(netdissect_options *ndo,
int i, j, n, trunc;
i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->rerr.r.dest6[0]);
- dp6 = &ap->rerr.r.dest6[0];
- n = ap->rerr.rerr_dc * j;
+ j = sizeof(ap->r.dest6[0]);
+ dp6 = &ap->r.dest6[0];
+ n = ap->rerr_dc * j;
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
- ap->rerr.rerr_dc, length));
+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr_dc, length));
trunc = n - (i/j);
for (; i -= j >= 0; ++dp6) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
@@ -442,11 +429,10 @@ aodv_v6_rerr(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rreq(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rreq6_draft_01 *ap, const u_char *dat, u_int length)
#else
aodv_v6_draft_01_rreq(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_,
- u_int length)
+ const struct aodv_rreq6_draft_01 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -457,26 +443,26 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rreq6_draft_01)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rreq6]"));
return;
}
- i -= sizeof(ap->rreq6_draft_01);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
- ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
- ap->rreq6_draft_01.rreq_hops,
- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id),
- ip6addr_string(ndo, &ap->rreq6_draft_01.rreq_da),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds),
- ip6addr_string(ndo, &ap->rreq6_draft_01.rreq_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os)));
+ ap->rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id),
+ ip6addr_string(ndo, &ap->rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
+ ip6addr_string(ndo, &ap->rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rreq6_draft_01 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " rreq %u", length));
#endif
@@ -485,11 +471,10 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rrep(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rrep6_draft_01 *ap, const u_char *dat, u_int length)
#else
aodv_v6_draft_01_rrep(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_,
- u_int length)
+ const struct aodv_rrep6_draft_01 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -500,23 +485,23 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rrep6_draft_01)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rrep6]"));
return;
}
- i -= sizeof(ap->rrep6_draft_01);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
- ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "",
- ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ",
- ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK,
- ap->rrep6_draft_01.rrep_hops,
- ip6addr_string(ndo, &ap->rrep6_draft_01.rrep_da),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds),
- ip6addr_string(ndo, &ap->rrep6_draft_01.rrep_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life)));
+ ap->rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep_hops,
+ ip6addr_string(ndo, &ap->rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
+ ip6addr_string(ndo, &ap->rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rrep6_draft_01 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " rrep %u", length));
#endif
@@ -525,10 +510,10 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const union aodv *ap, u_int length)
+ const struct aodv_rerr *ap, u_int length)
#else
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const union aodv *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, u_int length)
#endif
{
#ifdef INET6
@@ -536,12 +521,12 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo,
int i, j, n, trunc;
i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->rerr.r.dest6_draft_01[0]);
- dp6 = &ap->rerr.r.dest6_draft_01[0];
- n = ap->rerr.rerr_dc * j;
+ j = sizeof(ap->r.dest6_draft_01[0]);
+ dp6 = &ap->r.dest6_draft_01[0];
+ n = ap->rerr_dc * j;
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
- ap->rerr.rerr_dc, length));
+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr_dc, length));
trunc = n - (i/j);
for (; i -= j >= 0; ++dp6) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
@@ -558,40 +543,37 @@ void
aodv_print(netdissect_options *ndo,
const u_char *dat, u_int length, int is_ip6)
{
- const union aodv *ap;
-
- ap = (union aodv *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- if (min(length, (u_int)(ndo->ndo_snapend - dat)) < sizeof(ap->rrep_ack)) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
+ uint8_t msg_type;
+
+ /*
+ * The message type is the first byte; make sure we have it
+ * and then fetch it.
+ */
+ ND_TCHECK(*dat);
+ msg_type = *dat;
ND_PRINT((ndo, " aodv"));
- switch (ap->rerr.rerr_type) {
+ switch (msg_type) {
case AODV_RREQ:
if (is_ip6)
- aodv_v6_rreq(ndo, ap, dat, length);
+ aodv_v6_rreq(ndo, (const struct aodv_rreq6 *)dat, dat, length);
else
- aodv_rreq(ndo, ap, dat, length);
+ aodv_rreq(ndo, (const struct aodv_rreq *)dat, dat, length);
break;
case AODV_RREP:
if (is_ip6)
- aodv_v6_rrep(ndo, ap, dat, length);
+ aodv_v6_rrep(ndo, (const struct aodv_rrep6 *)dat, dat, length);
else
- aodv_rrep(ndo, ap, dat, length);
+ aodv_rrep(ndo, (const struct aodv_rrep *)dat, dat, length);
break;
case AODV_RERR:
if (is_ip6)
- aodv_v6_rerr(ndo, ap, length);
+ aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, length);
else
- aodv_rerr(ndo, ap, dat, length);
+ aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
break;
case AODV_RREP_ACK:
@@ -599,15 +581,15 @@ aodv_print(netdissect_options *ndo,
break;
case AODV_V6_DRAFT_01_RREQ:
- aodv_v6_draft_01_rreq(ndo, ap, dat, length);
+ aodv_v6_draft_01_rreq(ndo, (const struct aodv_rreq6_draft_01 *)dat, dat, length);
break;
case AODV_V6_DRAFT_01_RREP:
- aodv_v6_draft_01_rrep(ndo, ap, dat, length);
+ aodv_v6_draft_01_rrep(ndo, (const struct aodv_rrep6_draft_01 *)dat, dat, length);
break;
case AODV_V6_DRAFT_01_RERR:
- aodv_v6_draft_01_rerr(ndo, ap, length);
+ aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, length);
break;
case AODV_V6_DRAFT_01_RREP_ACK:
@@ -615,6 +597,10 @@ aodv_print(netdissect_options *ndo,
break;
default:
- ND_PRINT((ndo, " %u %u", ap->rreq.rreq_type, length));
+ ND_PRINT((ndo, " type %u %u", msg_type, length));
}
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|aodv]"));
}
--
2.1.2

View File

@ -1,3 +1,17 @@
-------------------------------------------------------------------
Fri Feb 6 12:31:23 UTC 2015 - vcizek@suse.com
- fix CVE-2014-8767 (bnc#905870)
* denial of service in verbose mode using malformed OLSR payload
* added tcpdump-CVE-2014-8767.patch
- fix CVE-2014-8768 (bnc#905871)
* denial of service in verbose mode using malformed Geonet payload
* added tcpdump-CVE-2014-8768.patch
- fix CVE-2014-8769 (bnc#905872)
* unreliable output using malformed AOVD payload
* added tcpdump-CVE-2014-8769.patch
* added 0001-Clean-up-error-message-printing.patch
-------------------------------------------------------------------
Wed Sep 3 18:44:03 UTC 2014 - andreas.stieger@gmx.de

View File

@ -1,7 +1,7 @@
#
# spec file for package tcpdump
#
# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -30,6 +30,10 @@ Source: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz
Source1: tcpdump-qeth
Source2: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz.sig
Source3: http://www.tcpdump.org/tcpdump-workers.asc#/%{name}.keyring
Patch3: tcpdump-CVE-2014-8767.patch
Patch4: tcpdump-CVE-2014-8768.patch
Patch5: tcpdump-CVE-2014-8769.patch
Patch6: 0001-Clean-up-error-message-printing.patch
BuildRequires: libpcap-devel >= %{min_libpcap_version}
BuildRequires: libsmi-devel
BuildRequires: openssl-devel
@ -42,6 +46,10 @@ ethernet. It can be used to debug specific network problems.
%prep
%setup -q
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%build
export CFLAGS="%{optflags} -Wall -DGUESS_TSO -fstack-protector -fno-strict-aliasing"