From 9c49d5a62ea975e8854719618c6c2c889eb205f9 Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Nov 20 2014 08:29:06 +0000 Subject: Fix for CVE-2014-8767 Resolves: #1165160 --- diff --git a/0009-Do-more-bounds-checking-and-length-checking.patch b/0009-Do-more-bounds-checking-and-length-checking.patch new file mode 100644 index 0000000..a97b109 --- /dev/null +++ b/0009-Do-more-bounds-checking-and-length-checking.patch @@ -0,0 +1,183 @@ +From 3b223228a87434f214ea3f80d9af420491a76434 Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Tue, 11 Nov 2014 16:49:39 -0800 +Subject: [PATCH 9/9] 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; + +-- +1.8.3.1 + diff --git a/tcpdump.spec b/tcpdump.spec index ce06d3b..853d4ed 100644 --- a/tcpdump.spec +++ b/tcpdump.spec @@ -20,6 +20,7 @@ Patch0005: 0005-tcpslice-remove-unneeded-include.patch Patch0006: 0006-tcpslice-don-t-test-the-pointer-but-pointee-for-NULL.patch Patch0007: 0007-Introduce-nn-option.patch Patch0008: 0008-Don-t-print-out-we-dropped-root-we-are-always-droppi.patch +Patch0009: 0009-Do-more-bounds-checking-and-length-checking.patch %define tcpslice_dir tcpslice-1.2a3 @@ -82,6 +83,9 @@ exit 0 %{_mandir}/man8/tcpdump.8* %changelog +* Thu Nov 20 2014 Michal Sekletar - 14:4.6.2-1 +- fix for CVE-2014-8767 (#1165160) + * Mon Oct 20 2014 Michal Sekletar - 14:4.6.2-1 - update to 4.6.2 (#1124289)