diff --git a/0010-Do-bounds-checking-and-length-checking.patch b/0010-Do-bounds-checking-and-length-checking.patch new file mode 100644 index 0000000..fff7bfb --- /dev/null +++ b/0010-Do-bounds-checking-and-length-checking.patch @@ -0,0 +1,343 @@ +From 9255c9b05b0a04b8d89739b3efcb9f393a617fe9 Mon Sep 17 00:00:00 2001 +From: Guy Harris +Date: Tue, 11 Nov 2014 15:51:54 -0800 +Subject: [PATCH] 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]")); + } + + +-- +1.8.3.1 + diff --git a/tcpdump.spec b/tcpdump.spec index 853d4ed..6fae5f9 100644 --- a/tcpdump.spec +++ b/tcpdump.spec @@ -21,6 +21,7 @@ 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 +Patch0010: 0010-Do-bounds-checking-and-length-checking.patch %define tcpslice_dir tcpslice-1.2a3 @@ -85,6 +86,7 @@ exit 0 %changelog * Thu Nov 20 2014 Michal Sekletar - 14:4.6.2-1 - fix for CVE-2014-8767 (#1165160) +- fix for CVE-2014-8768 (#1165161) * Mon Oct 20 2014 Michal Sekletar - 14:4.6.2-1 - update to 4.6.2 (#1124289)