b56a2c3b3f
- 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
184 lines
6.4 KiB
Diff
184 lines
6.4 KiB
Diff
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
|
|
|