head 1.9; access; symbols OPENPKG_E1_MP_HEAD:1.9 OPENPKG_E1_MP:1.9 OPENPKG_E1_MP_2_STABLE:1.8.4.1 OPENPKG_E1_FP:1.8.4.1 OPENPKG_2_STABLE_MP:1.9 OPENPKG_2_STABLE_20061018:1.8.4.1 OPENPKG_2_STABLE_20060622:1.8 OPENPKG_2_STABLE:1.8.0.4 OPENPKG_2_STABLE_BP:1.8 OPENPKG_2_5_RELEASE:1.8 OPENPKG_2_5_SOLID:1.8.0.2 OPENPKG_2_5_SOLID_BP:1.8 OPENPKG_2_4_RELEASE:1.7 OPENPKG_2_4_SOLID:1.7.0.8 OPENPKG_2_4_SOLID_BP:1.7 OPENPKG_CW_FP:1.7 OPENPKG_2_3_RELEASE:1.7 OPENPKG_2_3_SOLID:1.7.0.6 OPENPKG_2_3_SOLID_BP:1.7 OPENPKG_2_2_RELEASE:1.7 OPENPKG_2_2_SOLID:1.7.0.4 OPENPKG_2_2_SOLID_BP:1.7 OPENPKG_2_1_RELEASE:1.7 OPENPKG_2_1_SOLID:1.7.0.2 OPENPKG_2_1_SOLID_BP:1.7 OPENPKG_2_0_RELEASE:1.4 OPENPKG_2_0_SOLID:1.4.0.2 OPENPKG_2_0_SOLID_BP:1.4 OPENPKG_1_3_RELEASE:1.1.6.2 OPENPKG_1_3_SOLID:1.1.6.2.0.2 OPENPKG_1_3_SOLID_BP:1.1.6.2 OPENPKG_1_STABLE_MP:1.2 OPENPKG_1_STABLE:1.1.0.6 OPENPKG_1_2_SOLID:1.1.0.4 OPENPKG_1_1_SOLID:1.1.0.2; locks; strict; comment @# @; 1.9 date 2006.10.12.19.14.50; author rse; state Exp; branches; next 1.8; commitid DossEZXnVB6yBqQr; 1.8 date 2005.07.15.07.56.21; author rse; state Exp; branches 1.8.4.1; next 1.7; 1.7 date 2004.06.04.11.49.53; author ms; state Exp; branches; next 1.6; 1.6 date 2004.05.16.10.42.44; author rse; state Exp; branches; next 1.5; 1.5 date 2004.03.30.08.40.17; author ms; state dead; branches; next 1.4; 1.4 date 2004.01.16.12.37.39; author thl; state Exp; branches 1.4.2.1; next 1.3; 1.3 date 2003.12.30.09.47.27; author rse; state dead; branches; next 1.2; 1.2 date 2003.07.16.12.08.57; author mlelstv; state Exp; branches; next 1.1; 1.1 date 2003.02.28.12.19.57; author ms; state dead; branches 1.1.2.1 1.1.4.1 1.1.6.1; next ; 1.8.4.1 date 2006.10.16.14.57.04; author rse; state Exp; branches; next ; commitid iZxwRSmmWscPXUQr; 1.4.2.1 date 2004.04.06.15.39.44; author ms; state Exp; branches; next ; 1.1.2.1 date 2003.02.28.12.19.57; author ms; state Exp; branches; next 1.1.2.2; 1.1.2.2 date 2003.03.04.09.47.04; author rse; state Exp; branches; next ; 1.1.4.1 date 2003.02.28.12.34.02; author ms; state Exp; branches; next 1.1.4.2; 1.1.4.2 date 2003.03.04.09.45.17; author rse; state Exp; branches; next 1.1.4.3; 1.1.4.3 date 2004.01.16.12.40.29; author thl; state Exp; branches; next 1.1.4.4; 1.1.4.4 date 2004.01.16.12.42.52; author thl; state Exp; branches; next ; 1.1.6.1 date 2003.03.04.09.41.27; author rse; state Exp; branches; next 1.1.6.2; 1.1.6.2 date 2003.07.24.20.45.28; author rse; state Exp; branches 1.1.6.2.2.1; next ; 1.1.6.2.2.1 date 2004.01.16.12.38.59; author thl; state Exp; branches; next 1.1.6.2.2.2; 1.1.6.2.2.2 date 2004.04.07.15.44.02; author ms; state Exp; branches; next 1.1.6.2.2.3; 1.1.6.2.2.3 date 2004.04.07.16.08.01; author ms; state Exp; branches; next ; desc @@ 1.9 log @Hell, seems like I'm the only guy who cares about Solaris or what... fix tcpdump for Solaris @ text @The following patch fixes three custom Autoconf checks by moving the external references into the include section of the AC_TRY_LINK macro in order to make sure it is generated _outside_ the main() function. Else if generated _inside_ the main() function the test will always generate true because at least GCC then does not detect that the referenced symbol is actually undefined. Index: configure.in --- configure.in.orig 2005-09-21 18:50:01.000000000 +0200 +++ configure.in 2006-10-12 21:10:04.494299959 +0200 @@@@ -711,10 +711,10 @@@@ if test $ac_cv_func_pcap_lib_version = "no" ; then AC_MSG_CHECKING(whether pcap_version is defined by libpcap) - AC_TRY_LINK([], + AC_TRY_LINK( [ extern char pcap_version[]; - + ],[ return (int)pcap_version; ], ac_lbl_cv_pcap_version_defined=yes, @@@@ -727,10 +727,10 @@@@ fi fi AC_MSG_CHECKING(whether pcap_debug is defined by libpcap) -AC_TRY_LINK([], +AC_TRY_LINK( [ extern int pcap_debug; - + ],[ return pcap_debug; ], ac_lbl_cv_pcap_debug_defined=yes, @@@@ -744,10 +744,10 @@@@ # OK, what about "yydebug"? # AC_MSG_CHECKING(whether yydebug is defined by libpcap) - AC_TRY_LINK([], + AC_TRY_LINK( [ extern int yydebug; - + ],[ return yydebug; ], ac_lbl_cv_yydebug_defined=yes, Index: ether.h --- ether.h.orig 2002-12-11 08:13:51.000000000 +0100 +++ ether.h 2006-10-12 21:10:04.494616121 +0200 @@@@ -34,7 +34,9 @@@@ * @@(#)if_ether.h 8.3 (Berkeley) 5/2/95 */ +#ifndef ETHERMTU #define ETHERMTU 1500 +#endif /* * The number of bytes in an ethernet (MAC) address. @@@@ -44,7 +46,7 @@@@ /* * Structure of a DEC/Intel/Xerox or 802.3 Ethernet header. */ -struct ether_header { +struct tcpdump_ether_header { u_int8_t ether_dhost[ETHER_ADDR_LEN]; u_int8_t ether_shost[ETHER_ADDR_LEN]; u_int16_t ether_type; Index: print-ether.c --- print-ether.c.orig 2006-02-20 19:15:03.000000000 +0100 +++ print-ether.c 2006-10-12 21:10:04.494879335 +0200 @@@@ -79,8 +79,8 @@@@ static inline void ether_hdr_print(register const u_char *bp, u_int length) { - register const struct ether_header *ep; - ep = (const struct ether_header *)bp; + register const struct tcpdump_ether_header *ep; + ep = (const struct tcpdump_ether_header *)bp; (void)printf("%s > %s", etheraddr_string(ESRC(ep)), @@@@ -106,7 +106,7 @@@@ void ether_print(const u_char *p, u_int length, u_int caplen) { - struct ether_header *ep; + struct tcpdump_ether_header *ep; u_short ether_type; u_short extracted_ether_type; @@@@ -120,7 +120,7 @@@@ length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; - ep = (struct ether_header *)p; + ep = (struct tcpdump_ether_header *)p; p += ETHER_HDRLEN; ether_type = ntohs(ep->ether_type); Index: print-fddi.c --- print-fddi.c.orig 2005-11-13 13:12:59.000000000 +0100 +++ print-fddi.c 2006-10-12 21:10:04.495111950 +0200 @@@@ -242,7 +242,7 @@@@ fddi_print(const u_char *p, u_int length, u_int caplen) { const struct fddi_header *fddip = (const struct fddi_header *)p; - struct ether_header ehdr; + struct tcpdump_ether_header ehdr; u_short extracted_ethertype; if (caplen < FDDI_HDRLEN) { Index: print-ipfc.c --- print-ipfc.c.orig 2005-11-13 13:12:59.000000000 +0100 +++ print-ipfc.c 2006-10-12 21:10:04.495301089 +0200 @@@@ -81,7 +81,7 @@@@ ipfc_print(const u_char *p, u_int length, u_int caplen) { const struct ipfc_header *ipfcp = (const struct ipfc_header *)p; - struct ether_header ehdr; + struct tcpdump_ether_header ehdr; u_short extracted_ethertype; if (caplen < IPFC_HDRLEN) { Index: print-token.c --- print-token.c.orig 2005-11-13 13:13:01.000000000 +0100 +++ print-token.c 2006-10-12 21:10:47.628239160 +0200 @@@@ -102,7 +102,7 @@@@ { const struct token_header *trp; u_short extracted_ethertype; - struct ether_header ehdr; + struct tcpdump_ether_header ehdr; u_int route_len = 0, hdr_len = TOKEN_HDRLEN; int seg; @ 1.8 log @upgrading package: tcpdump 3.8.3 -> 3.9.3 @ text @d9 2 a10 2 --- configure.in.orig 2005-04-24 03:36:19 +0200 +++ configure.in 2005-07-15 09:42:17 +0200 d50 90 @ 1.8.4.1 log @Mass merge from CURRENT to 2-STABLE (all packages except those of JUNK class) @ text @d9 2 a10 2 --- configure.in.orig 2005-09-21 18:50:01.000000000 +0200 +++ configure.in 2006-10-12 21:10:04.494299959 +0200 a49 90 Index: ether.h --- ether.h.orig 2002-12-11 08:13:51.000000000 +0100 +++ ether.h 2006-10-12 21:10:04.494616121 +0200 @@@@ -34,7 +34,9 @@@@ * @@(#)if_ether.h 8.3 (Berkeley) 5/2/95 */ +#ifndef ETHERMTU #define ETHERMTU 1500 +#endif /* * The number of bytes in an ethernet (MAC) address. @@@@ -44,7 +46,7 @@@@ /* * Structure of a DEC/Intel/Xerox or 802.3 Ethernet header. */ -struct ether_header { +struct tcpdump_ether_header { u_int8_t ether_dhost[ETHER_ADDR_LEN]; u_int8_t ether_shost[ETHER_ADDR_LEN]; u_int16_t ether_type; Index: print-ether.c --- print-ether.c.orig 2006-02-20 19:15:03.000000000 +0100 +++ print-ether.c 2006-10-12 21:10:04.494879335 +0200 @@@@ -79,8 +79,8 @@@@ static inline void ether_hdr_print(register const u_char *bp, u_int length) { - register const struct ether_header *ep; - ep = (const struct ether_header *)bp; + register const struct tcpdump_ether_header *ep; + ep = (const struct tcpdump_ether_header *)bp; (void)printf("%s > %s", etheraddr_string(ESRC(ep)), @@@@ -106,7 +106,7 @@@@ void ether_print(const u_char *p, u_int length, u_int caplen) { - struct ether_header *ep; + struct tcpdump_ether_header *ep; u_short ether_type; u_short extracted_ether_type; @@@@ -120,7 +120,7 @@@@ length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; - ep = (struct ether_header *)p; + ep = (struct tcpdump_ether_header *)p; p += ETHER_HDRLEN; ether_type = ntohs(ep->ether_type); Index: print-fddi.c --- print-fddi.c.orig 2005-11-13 13:12:59.000000000 +0100 +++ print-fddi.c 2006-10-12 21:10:04.495111950 +0200 @@@@ -242,7 +242,7 @@@@ fddi_print(const u_char *p, u_int length, u_int caplen) { const struct fddi_header *fddip = (const struct fddi_header *)p; - struct ether_header ehdr; + struct tcpdump_ether_header ehdr; u_short extracted_ethertype; if (caplen < FDDI_HDRLEN) { Index: print-ipfc.c --- print-ipfc.c.orig 2005-11-13 13:12:59.000000000 +0100 +++ print-ipfc.c 2006-10-12 21:10:04.495301089 +0200 @@@@ -81,7 +81,7 @@@@ ipfc_print(const u_char *p, u_int length, u_int caplen) { const struct ipfc_header *ipfcp = (const struct ipfc_header *)p; - struct ether_header ehdr; + struct tcpdump_ether_header ehdr; u_short extracted_ethertype; if (caplen < IPFC_HDRLEN) { Index: print-token.c --- print-token.c.orig 2005-11-13 13:13:01.000000000 +0100 +++ print-token.c 2006-10-12 21:10:47.628239160 +0200 @@@@ -102,7 +102,7 @@@@ { const struct token_header *trp; u_short extracted_ethertype; - struct ether_header ehdr; + struct tcpdump_ether_header ehdr; u_int route_len = 0, hdr_len = TOKEN_HDRLEN; int seg; @ 1.7 log @avoid substitution of 'includes_' variable when treating 'des_cbc' in configure, and correct usage of AC_LIBOBJ throughout configure.in and configure @ text @d2 1 a2 1 defined test function into the include section of the AC_TRY_LINK macro d9 3 a11 35 --- configure.in.orig 2004-03-28 23:04:48.000000000 +0200 +++ configure.in 2004-06-04 13:23:17.308423700 +0200 @@@@ -513,7 +513,7 @@@@ AC_CHECK_FUNCS(vsnprintf snprintf,, [needsnprintf=yes]) if test $needsnprintf = yes; then - AC_LIBOBJ(snprintf.o) + AC_LIBOBJ(snprintf) fi AC_LBL_TYPE_SIGNAL @@@@ -550,7 +550,7 @@@@ #include ], [char src[4], dst[128]; inet_ntop(AF_INET, src, dst, sizeof(dst));], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) - AC_LIBOBJ(inet_ntop.o)]) + AC_LIBOBJ(inet_ntop)]) AC_MSG_CHECKING(for inet_pton) AC_TRY_LINK([#include #include @@@@ -558,7 +558,7 @@@@ #include ], [char src[128], dst[4]; inet_pton(AF_INET, src, dst);], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) - AC_LIBOBJ(inet_pton.o)]) + AC_LIBOBJ(inet_pton)]) AC_MSG_CHECKING(for inet_aton) AC_TRY_LINK([#include #include @@@@ -566,7 +566,7 @@@@ struct in_addr dst; inet_aton(src, &dst);], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) - AC_LIBOBJ(inet_aton.o)]) + AC_LIBOBJ(inet_aton)]) a12 4 dnl portability macros for getaddrinfo/getnameinfo dnl @@@@ -585,7 +585,7 @@@@ fi d18 5 a22 8 char * return_pcap_version(void) @@@@ -594,7 +594,7 @@@@ return pcap_version; } - ], + ],[], d24 1 a24 3 ac_lbl_cv_pcap_version_defined=no) if test "$ac_lbl_cv_pcap_version_defined" = yes ; then @@@@ -605,7 +605,7 @@@@ d31 3 a33 4 int return_pcap_debug(void) @@@@ -614,7 +614,7 @@@@ d35 1 a35 3 } - ], + ],[], d37 1 a37 3 ac_lbl_cv_pcap_debug_defined=no) if test "$ac_lbl_cv_pcap_debug_defined" = yes ; then @@@@ -626,7 +626,7 @@@@ d44 3 a46 4 int return_yydebug(void) @@@@ -635,7 +635,7 @@@@ d48 1 a48 3 } - ], + ],[] a49 122 ac_lbl_cv_yydebug_defined=no) if test "$ac_lbl_cv_yydebug_defined" = yes ; then Index: configure --- configure.orig 2004-03-28 23:06:09.000000000 +0200 +++ configure 2004-06-04 13:43:04.287404500 +0200 @@@@ -6836,7 +6836,7 @@@@ done if test $needsnprintf = yes; then - LIBOBJS="$LIBOBJS snprintf.o.$ac_objext" + LIBOBJS="$LIBOBJS snprintf.$ac_objext" fi @@@@ -8509,7 +8509,7 @@@@ echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 - LIBOBJS="$LIBOBJS inet_ntop.o.$ac_objext" + LIBOBJS="$LIBOBJS inet_ntop.$ac_objext" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext echo "$as_me:$LINENO: checking for inet_pton" >&5 @@@@ -8554,7 +8554,7 @@@@ echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 - LIBOBJS="$LIBOBJS inet_pton.o.$ac_objext" + LIBOBJS="$LIBOBJS inet_pton.$ac_objext" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext echo "$as_me:$LINENO: checking for inet_aton" >&5 @@@@ -8599,7 +8599,7 @@@@ echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 - LIBOBJS="$LIBOBJS inet_aton.o.$ac_objext" + LIBOBJS="$LIBOBJS inet_aton.$ac_objext" fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext @@@@ -8818,10 +8818,6 @@@@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -int -main () -{ - char * return_pcap_version(void) { @@@@ -8830,6 +8826,10 @@@@ return pcap_version; } +int +main () +{ + ; return 0; } @@@@ -8877,10 +8877,6 @@@@ /* end confdefs.h. */ int -main () -{ - -int return_pcap_debug(void) { extern int pcap_debug; @@@@ -8888,6 +8884,10 @@@@ return pcap_debug; } +int +main () +{ + ; return 0; } @@@@ -8935,10 +8935,6 @@@@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -int -main () -{ - int return_yydebug(void) { @@@@ -8947,6 +8943,11 @@@@ return yydebug; } +int +main () +{ + + ac_lbl_cv_yydebug_defined=yes ; return 0; } @@@@ -8963,12 +8964,11 @@@@ ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - ac_lbl_cv_yydebug_defined=yes + ac_lbl_cv_yydebug_defined=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -ac_lbl_cv_yydebug_defined=no fi rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext if test "$ac_lbl_cv_yydebug_defined" = yes ; then @ 1.6 log @fix tcpdump building against latest libpcap @ text @d10 37 a46 1 +++ configure.in 2004-05-16 12:36:59.000000000 +0200 d102 38 a139 2 --- configure.orig 2004-05-16 12:28:12.000000000 +0200 +++ configure 2004-05-16 12:37:45.000000000 +0200 @ 1.5 log @upgrading package: tcpdump 3.8.1 -> 3.8.2 @ text @d1 56 a56 40 tcpdump patch patrix; thl@@dev.de.cw.com tcpdump 371 371 372 381 OpenPKG 120 121 130 20020822 --- --- --- --- CAN-2002-0380 nfs y n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2002-1350 bgp y n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2003-0108 isakmp y n n n see past OpenPKG-SA-2003.014-tcpdump depth y y y n (*) CAN-2003-0989 isakmp y y y n updates CAN-2003-0108-isakmp CAN-2003-1029 l2tp y y n n CAN-2004-0055 radius y y y y CAN-2004-0057 isakmp y y y y (*) the vendor code fix for CAN-2003-0108 had two other unrelated code changes piggybacked. We removed the cosmetics (constify) and extracted an enhancement (depth). http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0055 (radius) The print_attr_string function in print-radius.c for tcpdump 3.8.1 and earlier allows remote attackers to cause a denial of service (segmentation fault) via a RADIUS attribute with a large length value. Index: print-radius.c =================================================================== RCS file: /tcpdump/master/tcpdump/print-radius.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -u -d -r1.23 -r1.24 --- print-radius.c.CAN-2004-0055 15 Dec 2003 13:52:15 -0000 1.23 +++ print-radius.c 7 Jan 2004 08:00:52 -0000 1.24 @@@@ -476,7 +476,7 @@@@ break; } - for (i=0; i < length ; i++, data++) + for (i=0; *data && i < length ; i++, data++) printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); d58 1 a58 42 return; http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0057 (isakmp) The rawprint function in the ISAKMP decoding routines (print-isakmp.c) for tcpdump 3.8.1 and earlier allows remote attackers to cause a denial of service (segmentation fault) via malformed ISAKMP packets that cause invalid "len" or "loc" values to be used in a loop, a different vulnerability than CAN-2003-0989. Index: print-isakmp.c =================================================================== RCS file: /tcpdump/master/tcpdump/print-isakmp.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -u -d -r1.41 -r1.42 --- print-isakmp.c.CAN-2004-0057 20 Dec 2003 10:03:19 -0000 1.41 +++ print-isakmp.c 7 Jan 2004 08:00:51 -0000 1.42 @@@@ -327,9 +327,13 @@@@ static u_char *p; size_t i; + TCHECK2(*loc, len); + p = (u_char *)loc; for (i = 0; i < len; i++) printf("%02x", p[i] & 0xff); +trunc: + return; } struct attrmap { @@@@ -1111,6 +1115,8 @@@@ cp = (const u_char *)ext; while (np) { + TCHECK2(*ext, sizeof(e)); + safememcpy(&e, ext, sizeof(e)); if (ep < (u_char *)ext + ntohs(e.len)) { @@@@ -1136,6 +1142,8 @@@@ ext = (struct isakmp_gen *)cp; d60 43 a102 3 return cp; +trunc: + return NULL; d105 44 a148 2 static char * @ 1.4 log @SA-2004.002-tcpdump; CAN-2004-0055, CAN-2004-0057 @ text @@ 1.4.2.1 log @OpenPKG-SA-2004.010-tcpdump (CAN-2004-0183 und CAN-2004-0184): Add patch code from a hand crafted 'diff tcpdump-3.8.1 tcpdump-3.8.2' to avoid denial of service from reading ISAKMP packets with malformed delete payloads and identification payloads @ text @d2 1 a2 1 tcpdump patch matrix; thl@@dev.de.cw.com d4 11 a14 13 tcpdump 371 371 372 381 381 OpenPKG 120 121 130 200 20040207 --- --- --- --- -------- CAN-2002-0380 nfs y n n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2002-1350 bgp y n n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2003-0108 isakmp y n n n n see past OpenPKG-SA-2003.014-tcpdump depth y y y n n (*) CAN-2003-0989 isakmp y y y n n updates CAN-2003-0108-isakmp CAN-2003-1029 l2tp y y n n n see past OpenPKG-SA-2004.002-tcpdump CAN-2004-0055 radius y y y y y see past OpenPKG-SA-2004.002-tcpdump CAN-2004-0057 isakmp y y y y y see past OpenPKG-SA-2004.002-tcpdump CAN-2004-0183 isakmp y y y y y CAN-2004-0184 isakmp y y y y y d59 1 a59 64 @@@@ -60,31 +60,31 @@@@ #endif static const u_char *isakmp_sa_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_p_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_t_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_ke_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_id_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_cert_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_cr_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_sig_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_hash_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_nonce_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_n_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_d_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_vid_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_sub0_print(u_char, const struct isakmp_gen *, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_sub_print(u_char, const struct isakmp_gen *, @@@@ -112,8 +112,8 @@@@ }; /* isakmp->np */ -static const u_char *(*npfunc[])(const struct isakmp_gen *, const u_char *, - u_int32_t, u_int32_t, u_int32_t, int) = { +static const u_char *(*npfunc[])(const struct isakmp_gen *, u_int, + const u_char *, u_int32_t, u_int32_t, u_int32_t, int) = { NULL, isakmp_sa_print, isakmp_p_print, @@@@ -321,15 +321,20 @@@@ return 0; } -static void +static int rawprint(caddr_t loc, size_t len) { a67 1 + return 1; d69 1 a69 1 + return 0; d73 1 a73 590 @@@@ -410,8 +415,10 @@@@ } static const u_char * -isakmp_sa_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, - u_int32_t doi0 _U_, u_int32_t proto0, int depth) +isakmp_sa_print(const struct isakmp_gen *ext, + u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0, int depth) { const struct isakmp_pl_sa *p; struct isakmp_pl_sa sa; @@@@ -423,6 +430,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_SA)); p = (struct isakmp_pl_sa *)ext; + TCHECK(*p); safememcpy(&sa, ext, sizeof(sa)); doi = ntohl(sa.doi); sit = ntohl(sa.sit); @@@@ -449,22 +457,28 @@@@ np = (u_char *)ext + sizeof(sa); if (sit != 0x01) { + TCHECK2(*(ext + 1), sizeof(ident)); safememcpy(&ident, ext + 1, sizeof(ident)); printf(" ident=%u", (u_int32_t)ntohl(ident)); np += sizeof(ident); } ext = (struct isakmp_gen *)np; + TCHECK(*ext); cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, depth); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA)); + return NULL; } static const u_char * -isakmp_p_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0 _U_, int depth) +isakmp_p_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0, + u_int32_t proto0 _U_, int depth) { const struct isakmp_pl_p *p; struct isakmp_pl_p prop; @@@@ -473,20 +487,26 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_P)); p = (struct isakmp_pl_p *)ext; + TCHECK(*p); safememcpy(&prop, ext, sizeof(prop)); printf(" #%d protoid=%s transform=%d", prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t); if (prop.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), prop.spi_size); + if (!rawprint((caddr_t)(p + 1), prop.spi_size)) + goto trunc; } ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + TCHECK(*ext); cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, prop.prot_id, depth); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_P)); + return NULL; } static const char *isakmp_p_map[] = { @@@@ -546,9 +566,9 @@@@ }; static const u_char * -isakmp_t_print(const struct isakmp_gen *ext, const u_char *ep, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto, - int depth _U_) +isakmp_t_print(const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto, int depth _U_) { const struct isakmp_pl_t *p; struct isakmp_pl_t t; @@@@ -561,6 +581,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); p = (struct isakmp_pl_t *)ext; + TCHECK(*p); safememcpy(&t, ext, sizeof(t)); switch (proto) { @@@@ -596,7 +617,7 @@@@ else printf(" #%d id=%d ", t.t_no, t.t_id); cp = (u_char *)(p + 1); - ep2 = (u_char *)p + ntohs(t.h.len); + ep2 = (u_char *)p + item_len; while (cp < ep && cp < ep2) { if (map && nmap) { cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2, @@@@ -607,30 +628,38 @@@@ if (ep < ep2) printf("..."); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T)); + return NULL; } static const u_char * -isakmp_ke_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_ke_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_KE)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" key len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE)); + return NULL; } static const u_char * -isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_id_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) { #define USE_IPSECDOI_IN_PHASE1 1 const struct isakmp_pl_id *p; @@@@ -649,12 +678,15 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_ID)); p = (struct isakmp_pl_id *)ext; + TCHECK(*p); safememcpy(&id, ext, sizeof(id)); - if (sizeof(*p) < id.h.len) + if (sizeof(*p) < item_len) { data = (u_char *)(p + 1); - else + len = item_len - sizeof(*p); + } else { data = NULL; - len = ntohs(id.h.len) - sizeof(*p); + len = 0; + } #if 0 /*debug*/ printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto); @@@@ -679,6 +711,7 @@@@ struct protoent *pe; p = (struct ipsecdoi_id *)ext; + TCHECK(*p); safememcpy(&id, ext, sizeof(id)); printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)); if (id.proto_id) { @@@@ -698,9 +731,15 @@@@ printf(" port=%d", ntohs(id.port)); if (!len) break; + if (data == NULL) + goto trunc; + TCHECK2(*data, len); switch (id.type) { case IPSECDOI_ID_IPV4_ADDR: - printf(" len=%d %s", len, ipaddr_string(data)); + if (len < 4) + printf(" len=%d [bad: < 4]", len); + else + printf(" len=%d %s", len, ipaddr_string(data)); len = 0; break; case IPSECDOI_ID_FQDN: @@@@ -716,39 +755,60 @@@@ case IPSECDOI_ID_IPV4_ADDR_SUBNET: { const u_char *mask; - mask = data + sizeof(struct in_addr); - printf(" len=%d %s/%u.%u.%u.%u", len, - ipaddr_string(data), - mask[0], mask[1], mask[2], mask[3]); + if (len < 8) + printf(" len=%d [bad: < 8]", len); + else { + mask = data + sizeof(struct in_addr); + printf(" len=%d %s/%u.%u.%u.%u", len, + ipaddr_string(data), + mask[0], mask[1], mask[2], mask[3]); + } len = 0; break; } #ifdef INET6 case IPSECDOI_ID_IPV6_ADDR: - printf(" len=%d %s", len, ip6addr_string(data)); + if (len < 16) + printf(" len=%d [bad: < 16]", len); + else + printf(" len=%d %s", len, ip6addr_string(data)); len = 0; break; case IPSECDOI_ID_IPV6_ADDR_SUBNET: { const u_int32_t *mask; - mask = (u_int32_t *)(data + sizeof(struct in6_addr)); - /*XXX*/ - printf(" len=%d %s/0x%08x%08x%08x%08x", len, - ip6addr_string(data), - mask[0], mask[1], mask[2], mask[3]); + if (len < 20) + printf(" len=%d [bad: < 20]", len); + else { + mask = (u_int32_t *)(data + sizeof(struct in6_addr)); + /*XXX*/ + printf(" len=%d %s/0x%08x%08x%08x%08x", len, + ip6addr_string(data), + mask[0], mask[1], mask[2], mask[3]); + } len = 0; break; } #endif /*INET6*/ case IPSECDOI_ID_IPV4_ADDR_RANGE: - printf(" len=%d %s-%s", len, ipaddr_string(data), - ipaddr_string(data + sizeof(struct in_addr))); + if (len < 8) + printf(" len=%d [bad: < 8]", len); + else { + printf(" len=%d %s-%s", len, + ipaddr_string(data), + ipaddr_string(data + sizeof(struct in_addr))); + } len = 0; break; #ifdef INET6 case IPSECDOI_ID_IPV6_ADDR_RANGE: - printf(" len=%d %s-%s", len, ip6addr_string(data), - ip6addr_string(data + sizeof(struct in6_addr))); + if (len < 32) + printf(" len=%d [bad: < 32]", len); + else { + printf(" len=%d %s-%s", len, + ip6addr_string(data), + ip6addr_string(data + sizeof(struct in6_addr))); + } len = 0; break; #endif /*INET6*/ @@@@ -764,16 +824,21 @@@@ printf(" len=%d", len); if (2 < vflag) { printf(" "); - rawprint((caddr_t)data, len); + if (!rawprint((caddr_t)data, len)) + goto trunc; } } - return (u_char *)ext + ntohs(id.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID)); + return NULL; } static const u_char * -isakmp_cert_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_, - int depth _U_) +isakmp_cert_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, + u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) { const struct isakmp_pl_cert *p; struct isakmp_pl_cert cert; @@@@ -786,20 +851,25 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); - printf(" len=%d", ntohs(cert.h.len) - 4); + printf(" len=%d", item_len - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); - if (2 < vflag && 4 < ntohs(cert.h.len)) { + if (2 < vflag && 4 < item_len) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); + if (!rawprint((caddr_t)(ext + 1), item_len - 4)) + goto trunc; } - return (u_char *)ext + ntohs(cert.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)); + return NULL; } static const u_char * -isakmp_cr_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_, - int depth _U_) +isakmp_cr_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) { const struct isakmp_pl_cert *p; struct isakmp_pl_cert cert; @@@@ -812,73 +882,96 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_CR)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); - printf(" len=%d", ntohs(cert.h.len) - 4); + printf(" len=%d", item_len - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); - if (2 < vflag && 4 < ntohs(cert.h.len)) { + if (2 < vflag && 4 < item_len) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); + if (!rawprint((caddr_t)(ext + 1), item_len - 4)) + goto trunc; } - return (u_char *)ext + ntohs(cert.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR)); + return NULL; } static const u_char * -isakmp_hash_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_hash_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)); + return NULL; } static const u_char * -isakmp_sig_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_sig_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)); + return NULL; } static const u_char * -isakmp_nonce_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_nonce_print(const struct isakmp_gen *ext, + u_int item_len _U_, + const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" n len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)); + return NULL; } static const u_char * -isakmp_n_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, - u_int32_t doi0 _U_, u_int32_t proto0 _U_, int depth) +isakmp_n_print(const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth) { struct isakmp_pl_n *p, n; const u_char *cp; @@@@ -934,6 +1027,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_N)); p = (struct isakmp_pl_n *)ext; + TCHECK(*p); safememcpy(&n, ext, sizeof(n)); doi = ntohl(n.doi); proto = n.prot_id; @@@@ -950,7 +1044,8 @@@@ printf(" type=%s", numstr(ntohs(n.type))); if (n.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), n.spi_size); + if (!rawprint((caddr_t)(p + 1), n.spi_size)) + goto trunc; } return (u_char *)(p + 1) + n.spi_size; } @@@@ -969,11 +1064,12 @@@@ printf(" type=%s", numstr(ntohs(n.type))); if (n.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), n.spi_size); + if (!rawprint((caddr_t)(p + 1), n.spi_size)) + goto trunc; } cp = (u_char *)(p + 1) + n.spi_size; - ep2 = (u_char *)p + ntohs(n.h.len); + ep2 = (u_char *)p + item_len; if (cp < ep) { printf(" orig=("); @@@@ -1000,19 +1096,21 @@@@ break; default: /* NULL is dummy */ - isakmp_print(cp, - ntohs(n.h.len) - sizeof(*p) - n.spi_size, + isakmp_print(cp, item_len - sizeof(*p) - n.spi_size, NULL); } printf(")"); } - return (u_char *)ext + ntohs(n.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N)); + return NULL; } static const u_char * -isakmp_d_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_, - int depth _U_) +isakmp_d_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) { const struct isakmp_pl_d *p; struct isakmp_pl_d d; @@@@ -1024,6 +1122,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_D)); p = (struct isakmp_pl_d *)ext; + TCHECK(*p); safememcpy(&d, ext, sizeof(d)); doi = ntohl(d.doi); proto = d.prot_id; @@@@ -1041,28 +1140,38 @@@@ for (i = 0; i < ntohs(d.num_spi); i++) { if (i != 0) printf(","); - rawprint((caddr_t)q, d.spi_size); + if (!rawprint((caddr_t)q, d.spi_size)) + goto trunc; q += d.spi_size; } return q; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D)); + return NULL; } static const u_char * -isakmp_vid_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_vid_print(const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_VID)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID)); + return NULL; } static const u_char * @@@@ -1074,6 +1183,7 @@@@ u_int item_len; cp = (u_char *)ext; + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); /* @@@@ -1091,13 +1201,16 @@@@ * XXX - what if item_len is too short, or too long, * for this payload type? */ - cp = (*NPFUNC(np))(ext, ep, phase, doi, proto, depth); + cp = (*NPFUNC(np))(ext, item_len, ep, phase, doi, proto, depth); } else { printf("%s", NPSTR(np)); cp += item_len; } return cp; +trunc: + printf(" [|isakmp]"); + return NULL; } static const u_char * @@@@ -1111,13 +1224,12 @@@@ d77 1 a77 1 + TCHECK(*ext); d81 2 a82 11 - if (ep < (u_char *)ext + ntohs(e.len)) { - printf(" [|%s]", NPSTR(np)); - cp = ep + 1; - break; - } + TCHECK2(*ext, ntohs(e.len)); + depth++; printf("\n"); for (i = 0; i < depth; i++) @@@@ -1136,6 +1248,9 @@@@ a86 1 + printf(" [|%s]", NPSTR(np)); d91 1 a91 9 @@@@ -1263,7 +1378,7 @@@@ done: if (vflag) { if (ntohl(base.len) != length) { - printf(" (len mismatch: isakmp %u/ip %d)", + printf(" (len mismatch: isakmp %u/ip %u)", (u_int32_t)ntohl(base.len), length); } } @ 1.3 log @upgrading package: tcpdump 3.7.2 -> 3.8.1 @ text @d1 36 a36 17 --- print-sctp.c.dist 2003-07-16 13:52:36.000000000 +0200 +++ print-sctp.c 2003-07-16 14:00:32.000000000 +0200 @@@@ -46,13 +46,13 @@@@ #include #include +#include + #include #include "sctpHeader.h" #include "sctpConstants.h" #include -#include - #include #include d38 54 @ 1.2 log @avoid clashes with system headers @ text @@ 1.1 log @file tcpdump.patch was initially added on branch OPENPKG_1_1_SOLID. @ text @d1 18 @ 1.1.6.1 log @apply security patch (see OpenPKG-SA-2003.014-tcpdump); merge in OpenSSL DES fixes @ text @a0 242 --- print-bgp.c Thu Oct 18 11:52:17 2001 +++ print-bgp.c Tue Mar 4 10:33:39 2003 @@@@ -469,11 +469,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #endif @@@@ -505,11 +513,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #endif @@@@ -598,6 +614,7 @@@@ printf(" (Withdrawn routes: %d bytes)", len); #else char buf[MAXHOSTNAMELEN + 100]; + int wpfx; TCHECK2(p[2], len); i = 2; @@@@ -605,7 +622,10 @@@@ printf(" (Withdrawn routes:"); while(i < 2 + len) { - i += decode_prefix4(&p[i], buf, sizeof(buf)); + wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); + if (wpfx < 0) + break; + i += wpfx; printf(" %s", buf); } printf(")\n"); @@@@ -666,9 +686,9 @@@@ while (dat + length > p) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); - printf(" %s", buf); if (i < 0) break; + printf(" %s", buf); p += i; } --- print-isakmp.c Fri Oct 26 05:41:29 2001 +++ print-isakmp.c Tue Mar 4 10:33:39 2003 @@@@ -1028,6 +1028,7 @@@@ { u_char *cp; struct isakmp_gen e; + u_int item_len; cp = (u_char *)ext; safememcpy(&e, ext, sizeof(e)); @@@@ -1036,7 +1037,16 @@@@ cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); else { printf("%s", NPSTR(np)); - cp += ntohs(e.len); + item_len = ntohs(e.len); + if (item_len == 0) { + /* + * We don't want to loop forever processing this + * bogus (zero-length) item; return NULL so that + * we stop dissecting. + */ + cp = NULL; + } else + cp += item_len; } return cp; } @@@@ -1068,6 +1078,11 @@@@ cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto); printf(")"); depth--; + + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } np = e.np; ext = (struct isakmp_gen *)cp; --- print-nfs.c Sun Jul 8 10:01:43 2001 +++ print-nfs.c Tue Mar 4 10:33:39 2003 @@@@ -716,10 +716,16 @@@@ case NFSPROC_FSINFO: printf(" fsinfo"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_PATHCONF: printf(" pathconf"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_COMMIT: @@@@ -1027,7 +1033,6 @@@@ printf(" ERROR: %s", tok2str(status2str, "unk %d", errnum)); nfserr = 1; - return (NULL); } return (dp + 1); trunc: @@@@ -1109,8 +1114,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); return (parsefattr(dp, verbose, v3) != NULL); } @@@@ -1120,8 +1127,10 @@@@ { int er; - if (!(dp = parsestatus(dp, &er)) || er) + if (!(dp = parsestatus(dp, &er))) return (0); + if (er) + return (1); dp = parsefh(dp, 0); if (dp == NULL) @@@@ -1136,8 +1145,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return(0); + if (er) + return(1); if (v3 && !(dp = parse_post_op_attr(dp, vflag))) return (0); putchar(' '); @@@@ -1151,8 +1162,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || (!v3 && er)) + if (dp == NULL) return (0); + if (!v3 && er) + return (1); if (qflag) return(1); @@@@ -1164,7 +1177,7 @@@@ return (0); } - TCHECK2(dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); + TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); sfsp = (const struct nfs_statfs *)dp; @@@@ -1205,8 +1218,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); if (qflag) return (1); @@@@ -1242,7 +1257,7 @@@@ if (!ntohl(dp[0])) return (dp + 1); dp++; - TCHECK2(dp, 24); + TCHECK2(*dp, 24); if (verbose > 1) { return parse_wcc_attr(dp); } else { @@@@ -1379,9 +1394,9 @@@@ (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_sec), (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_nsec)); } - return (0); -trunc: return (1); +trunc: + return (0); } static int @@@@ -1409,9 +1424,9 @@@@ ntohl(spp->pc_chownrestricted) ? "chownres" : "", ntohl(spp->pc_caseinsensitive) ? "igncase" : "", ntohl(spp->pc_casepreserving) ? "keepcase" : ""); - return (0); -trunc: return (1); +trunc: + return (0); } static void @ 1.1.6.2 log @mass Merge-From-CURRENT (MFC) in preparation for OpenPKG 1.3 [class BASE only] @ text @d1 47 a47 5 --- print-sctp.c.dist 2003-07-16 13:52:36.000000000 +0200 +++ print-sctp.c 2003-07-16 14:00:32.000000000 +0200 @@@@ -46,13 +46,13 @@@@ #include #include d49 57 a105 1 +#include d107 134 a240 9 #include #include "sctpHeader.h" #include "sctpConstants.h" #include -#include - #include #include d242 1 @ 1.1.6.2.2.1 log @SA-2004.002-tcpdump; CAN-2003-0989, CAN-2004-0055, CAN-2004-0057 @ text @a18 476 tcpdump patch patrix; thl@@dev.de.cw.com tcpdump 371 371 372 381 OpenPKG 120 121 130 20020822 --- --- --- --- CAN-2002-0380 nfs y n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2002-1350 bgp y n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2003-0108 isakmp y n n n see past OpenPKG-SA-2003.014-tcpdump depth y y y n (*) CAN-2003-0989 isakmp y y y n updates CAN-2003-0108-isakmp CAN-2003-1029 l2tp y y n n CAN-2004-0055 radius y y y y CAN-2004-0057 isakmp y y y y (*) the vendor code fix for CAN-2003-0108 had two other unrelated code changes piggybacked. We removed the cosmetics (constify) and extracted an enhancement (depth). http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0108 (depth) Not directly related to the CVE security topic but piggybacked. revision 1.34 date: 2002/09/05 00:43:21; author: guy; state: Exp; lines: +155 -127 1.) print-isakmp.c: Constify. [undone to reduce patch] 2.) [real security issue as of CAN-2003-0108] 3.) Have "isakmp_sub_print()" take the depth as an argument, rather than have it as a static variable, for cleanliness. Index: print-isakmp.c --- print-isakmp.c.CAN-2003-0108 2004-01-15 16:30:04.000000000 +0100 +++ print-isakmp.c 2004-01-15 16:31:28.000000000 +0100 @@@@ -67,36 +67,36 @@@@ #define sockaddr_storage sockaddr #endif -static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); +static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); static u_char *isakmp_p_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_t_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_ke_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_id_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_cert_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_cr_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_sig_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); -static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); -static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); +static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); +static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); static u_char *isakmp_n_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_d_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_vid_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); -static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); -static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); +static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); +static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); static char *numstr(int); static void safememcpy(void *, void *, size_t); @@@@ -121,7 +121,7 @@@@ /* isakmp->np */ static u_char *(*npfunc[])(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t) = { + u_int32_t, u_int32_t, int) = { NULL, isakmp_sa_print, isakmp_p_print, @@@@ -333,7 +333,7 @@@@ rawprint(caddr_t loc, size_t len) { static u_char *p; - int i; + size_t i; p = (u_char *)loc; for (i = 0; i < len; i++) @@@@ -342,7 +342,7 @@@@ struct attrmap { char *type; - int nvalue; + u_int nvalue; char *value[30]; /*XXX*/ }; @@@@ -418,7 +418,7 @@@@ static u_char * isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_sa *p, sa; u_int32_t *q; @@@@ -462,14 +462,14 @@@@ ext = (struct isakmp_gen *)np; - cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0); + cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, depth); return cp; } static u_char * isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_p *p, prop; u_char *cp; @@@@ -488,7 +488,7 @@@@ ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, - prop.prot_id); + prop.prot_id, depth); return cp; } @@@@ -551,7 +551,7 @@@@ static u_char * isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_pl_t *p, t; u_char *cp; @@@@ -613,7 +613,7 @@@@ static u_char * isakmp_ke_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -630,7 +630,7 @@@@ static u_char * isakmp_id_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { #define USE_IPSECDOI_IN_PHASE1 1 struct isakmp_pl_id *p, id; @@@@ -766,7 +766,7 @@@@ static u_char * isakmp_cert_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_cert *p, cert; static char *certstr[] = { @@@@ -790,7 +790,7 @@@@ static u_char * isakmp_cr_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_cert *p, cert; static char *certstr[] = { @@@@ -814,7 +814,7 @@@@ static u_char * isakmp_hash_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -831,7 +831,7 @@@@ static u_char * isakmp_sig_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -848,7 +848,7 @@@@ static u_char * isakmp_nonce_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -865,7 +865,7 @@@@ static u_char * isakmp_n_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_n *p, n; u_char *cp; @@@@ -955,8 +955,9 @@@@ (*(u_int32_t *)cp) ? "en" : "dis"); break; case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: - isakmp_sub_print(ISAKMP_NPTYPE_SA, - (struct isakmp_gen *)cp, ep, phase, doi, proto); + if (isakmp_sub_print(ISAKMP_NPTYPE_SA, + (struct isakmp_gen *)cp, ep, phase, doi, proto, depth) == NULL) + return NULL; break; default: /* NULL is dummy */ @@@@ -971,7 +972,7 @@@@ static u_char * isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_d *p, d; u_int8_t *q; @@@@ -1007,7 +1008,7 @@@@ static u_char * isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -1024,7 +1025,7 @@@@ static u_char * isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep, - u_int32_t phase, u_int32_t doi, u_int32_t proto) + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) { u_char *cp; struct isakmp_gen e; @@@@ -1053,10 +1053,9 @@@@ static u_char * isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep, - u_int32_t phase, u_int32_t doi, u_int32_t proto) + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) { u_char *cp; - static int depth = 0; int i; struct isakmp_gen e; @@@@ -1075,7 +1080,7 @@@@ for (i = 0; i < depth; i++) printf(" "); printf("("); - cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto); + cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto, depth); printf(")"); depth--; @@@@ -1180,35 +1185,36 @@@@ printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "", base.flags & ISAKMP_FLAG_C ? "C" : ""); } - printf(":"); - { - struct isakmp_gen *ext; - int nparen; + if (vflag) { + struct isakmp_gen *ext; + int nparen; #define CHECKLEN(p, np) \ - if (ep < (u_char *)(p)) { \ - printf(" [|%s]", NPSTR(np)); \ - goto done; \ - } + if (ep < (u_char *)(p)) { \ + printf(" [|%s]", NPSTR(np)); \ + goto done; \ + } - /* regardless of phase... */ - if (base.flags & ISAKMP_FLAG_E) { - /* - * encrypted, nothing we can do right now. - * we hope to decrypt the packet in the future... - */ - printf(" [encrypted %s]", NPSTR(base.np)); - goto done; - } + printf(":"); - nparen = 0; - CHECKLEN(p + 1, base.np) + /* regardless of phase... */ + if (base.flags & ISAKMP_FLAG_E) { + /* + * encrypted, nothing we can do right now. + * we hope to decrypt the packet in the future... + */ + printf(" [encrypted %s]", NPSTR(base.np)); + goto done; + } - np = base.np; - ext = (struct isakmp_gen *)(p + 1); - isakmp_sub_print(np, ext, ep, phase, 0, 0); - } + nparen = 0; + CHECKLEN(p + 1, base.np) + + np = base.np; + ext = (struct isakmp_gen *)(p + 1); + isakmp_sub_print(np, ext, ep, phase, 0, 0, 0); + } done: if (vflag) { http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0989 (isakmp) tcpdump before 3.8.1 allows remote attackers to cause a denial of service (infinite loop) via certain ISAKMP packets, a different vulnerability than CAN-2004-0057. Index: print-isakmp.c --- print-isakmp.c.CAN-2003-0989 2004-01-15 16:30:04.000000000 +0100 +++ print-isakmp.c 2004-01-15 16:31:28.000000000 +0100 @@@@ -1033,20 +1034,25 @@@@ cp = (u_char *)ext; safememcpy(&e, ext, sizeof(e)); - if (NPFUNC(np)) - cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); - else { + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + return NULL; + + if (NPFUNC(np)) { + /* + * XXX - what if item_len is too short, or too long, + * for this payload type? + */ + cp = (*NPFUNC(np))(ext, ep, phase, doi, proto, depth); + } else { printf("%s", NPSTR(np)); - item_len = ntohs(e.len); - if (item_len == 0) { - /* - * We don't want to loop forever processing this - * bogus (zero-length) item; return NULL so that - * we stop dissecting. - */ - cp = NULL; - } else - cp += item_len; + cp += item_len; } return cp; } http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0055 (radius) The print_attr_string function in print-radius.c for tcpdump 3.8.1 and earlier allows remote attackers to cause a denial of service (segmentation fault) via a RADIUS attribute with a large length value. Index: print-radius.c =================================================================== RCS file: /tcpdump/master/tcpdump/print-radius.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -u -d -r1.23 -r1.24 --- print-radius.c.CAN-2004-0055 15 Dec 2003 13:52:15 -0000 1.23 +++ print-radius.c 7 Jan 2004 08:00:52 -0000 1.24 @@@@ -476,7 +476,7 @@@@ break; } - for (i=0; i < length ; i++, data++) + for (i=0; *data && i < length ; i++, data++) printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); return; http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0057 (isakmp) The rawprint function in the ISAKMP decoding routines (print-isakmp.c) for tcpdump 3.8.1 and earlier allows remote attackers to cause a denial of service (segmentation fault) via malformed ISAKMP packets that cause invalid "len" or "loc" values to be used in a loop, a different vulnerability than CAN-2003-0989. Index: print-isakmp.c =================================================================== RCS file: /tcpdump/master/tcpdump/print-isakmp.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -u -d -r1.41 -r1.42 --- print-isakmp.c.CAN-2004-0057 20 Dec 2003 10:03:19 -0000 1.41 +++ print-isakmp.c 7 Jan 2004 08:00:51 -0000 1.42 @@@@ -327,9 +327,13 @@@@ static u_char *p; size_t i; + TCHECK2(*loc, len); + p = (u_char *)loc; for (i = 0; i < len; i++) printf("%02x", p[i] & 0xff); +trunc: + return; } struct attrmap { @@@@ -1111,6 +1115,8 @@@@ cp = (const u_char *)ext; while (np) { + TCHECK2(*ext, sizeof(e)); + safememcpy(&e, ext, sizeof(e)); if (ep < (u_char *)ext + ntohs(e.len)) { @@@@ -1136,6 +1142,8 @@@@ ext = (struct isakmp_gen *)cp; } return cp; +trunc: + return NULL; } static char * @ 1.1.6.2.2.2 log @OpenPKG-SA-2004.010-tcpdump (CAN-2004-0183 and CAN-2004-0184): Integrate patch code from debian's tcpdump_3.7.2-4.diff.gz to avoid denial of service from reading ISAKMP packets with malformed delete payloads and identification payloads @ text @d22 11 a32 13 tcpdump 371 371 372 372 381 OpenPKG 120 121 130 131 20020822 --- --- --- --- --- CAN-2002-0380 nfs y n n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2002-1350 bgp y n n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2003-0108 isakmp y n n n n see past OpenPKG-SA-2003.014-tcpdump depth y y y n n (*) CAN-2003-0989 isakmp y y y n n updates CAN-2003-0108-isakmp CAN-2003-1029 l2tp y y n n n CAN-2004-0055 radius y y y y y CAN-2004-0057 isakmp y y y y y CAN-2004-0183 isakmp y y y y y CAN-2004-0184 isakmp y y y y y a494 482 Index: print-isakmp.c diff -Nau print-isakmp.c.CAN-2004-0183 print-isakmp.c --- print-isakmp.c.CAN-2004-0183 2004-04-07 16:29:55.000000000 +0200 +++ print-isakmp.c 2004-04-07 17:16:45.000000000 +0200 @@@@ -326,7 +326,7 @@@@ return 0; } -static void +static int rawprint(caddr_t loc, size_t len) { static u_char *p; @@@@ -337,8 +337,9 @@@@ p = (u_char *)loc; for (i = 0; i < len; i++) printf("%02x", p[i] & 0xff); + return 1; trunc: - return; + return 0; } struct attrmap { @@@@ -430,6 +431,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_SA)); p = (struct isakmp_pl_sa *)ext; + TCHECK(*p); safememcpy(&sa, ext, sizeof(sa)); doi = ntohl(sa.doi); sit = ntohl(sa.sit); @@@@ -456,16 +458,21 @@@@ np = (u_char *)ext + sizeof(sa); if (sit != 0x01) { + TCHECK2(*(ext + 1), sizeof(ident)); safememcpy(&ident, ext + 1, sizeof(ident)); printf(" ident=%u", (u_int32_t)ntohl(ident)); np += sizeof(ident); } ext = (struct isakmp_gen *)np; + TCHECK(*ext); cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, depth); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA)); + return NULL; } static u_char * @@@@ -478,20 +485,26 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_P)); p = (struct isakmp_pl_p *)ext; + TCHECK(*p); safememcpy(&prop, ext, sizeof(prop)); printf(" #%d protoid=%s transform=%d", prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t); if (prop.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), prop.spi_size); + if (!rawprint((caddr_t)(p + 1), prop.spi_size)) + goto trunc; } ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + TCHECK(*ext); cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, prop.prot_id, depth); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_P)); + return NULL; } static char *isakmp_p_map[] = { @@@@ -564,6 +577,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); p = (struct isakmp_pl_t *)ext; + TCHECK(*p); safememcpy(&t, ext, sizeof(t)); switch (proto) { @@@@ -610,6 +624,9 @@@@ if (ep < ep2) printf("..."); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T)); + return NULL; } static u_char * @@@@ -620,13 +637,18 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_KE)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" key len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE)); + return NULL; } static u_char * @@@@ -649,12 +671,15 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_ID)); p = (struct isakmp_pl_id *)ext; + TCHECK(*p); safememcpy(&id, ext, sizeof(id)); - if (sizeof(*p) < id.h.len) + if (sizeof(*p) < ntohs(id.h.len)) { data = (u_char *)(p + 1); - else + len = ntohs(id.h.len) - sizeof(*p); + } else { data = NULL; - len = ntohs(id.h.len) - sizeof(*p); + len = 0; + } #if 0 /*debug*/ printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto); @@@@ -678,6 +703,7 @@@@ struct protoent *pe; p = (struct ipsecdoi_id *)ext; + TCHECK(*p); safememcpy(&id, ext, sizeof(id)); printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)); if (id.proto_id) { @@@@ -693,9 +719,15 @@@@ printf(" port=%d", ntohs(id.port)); if (!len) break; + if (data == NULL) + goto trunc; + TCHECK2(*data, len); switch (id.type) { case IPSECDOI_ID_IPV4_ADDR: - printf(" len=%d %s", len, ipaddr_string(data)); + if (len < 4) + printf(" len=%d [bad: < 4]", len); + else + printf(" len=%d %s", len, ipaddr_string(data)); len = 0; break; case IPSECDOI_ID_FQDN: @@@@ -711,39 +743,58 @@@@ case IPSECDOI_ID_IPV4_ADDR_SUBNET: { u_char *mask; - mask = data + sizeof(struct in_addr); - printf(" len=%d %s/%u.%u.%u.%u", len, - ipaddr_string(data), - mask[0], mask[1], mask[2], mask[3]); + if (len < 8) + printf(" len=%d [bad: < 8]", len); + else { + mask = data + sizeof(struct in_addr); + printf(" len=%d %s/%u.%u.%u.%u", len, + ipaddr_string(data), + mask[0], mask[1], mask[2], mask[3]); + } len = 0; break; } #ifdef INET6 case IPSECDOI_ID_IPV6_ADDR: - printf(" len=%d %s", len, ip6addr_string(data)); + if (len < 16) + printf(" len=%d [bad: < 16]", len); + else + printf(" len=%d %s", len, ip6addr_string(data)); len = 0; break; case IPSECDOI_ID_IPV6_ADDR_SUBNET: { u_int32_t *mask; - mask = (u_int32_t *)(data + sizeof(struct in6_addr)); - /*XXX*/ - printf(" len=%d %s/0x%08x%08x%08x%08x", len, - ip6addr_string(data), - mask[0], mask[1], mask[2], mask[3]); + if (len < 20) + printf(" len=%d [bad: < 20]", len); + else { + mask = (u_int32_t *)(data + sizeof(struct in6_addr)); + /*XXX*/ + printf(" len=%d %s/0x%08x%08x%08x%08x", len, + ip6addr_string(data), + mask[0], mask[1], mask[2], mask[3]); + } len = 0; break; } #endif /*INET6*/ case IPSECDOI_ID_IPV4_ADDR_RANGE: - printf(" len=%d %s-%s", len, ipaddr_string(data), - ipaddr_string(data + sizeof(struct in_addr))); + if (len < 8) + printf(" len=%d [bad: < 8]", len); + else { + printf(" len=%d %s-%s", len, ipaddr_string(data), + ipaddr_string(data + sizeof(struct in_addr))); + } len = 0; break; #ifdef INET6 case IPSECDOI_ID_IPV6_ADDR_RANGE: - printf(" len=%d %s-%s", len, ip6addr_string(data), - ip6addr_string(data + sizeof(struct in6_addr))); + if (len < 32) + printf(" len=%d [bad: < 32]", len); + else { + printf(" len=%d %s-%s", len, ip6addr_string(data), + ip6addr_string(data + sizeof(struct in6_addr))); + } len = 0; break; #endif /*INET6*/ @@@@ -759,10 +810,14 @@@@ printf(" len=%d", len); if (2 < vflag) { printf(" "); - rawprint((caddr_t)data, len); + if (!rawprint((caddr_t)data, len)) + goto trunc; } } return (u_char *)ext + ntohs(id.h.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID)); + return NULL; } static u_char * @@@@ -779,14 +834,19 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); printf(" len=%d", ntohs(cert.h.len) - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); if (2 < vflag && 4 < ntohs(cert.h.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(cert.h.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)); + return NULL; } static u_char * @@@@ -803,14 +863,19 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_CR)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); printf(" len=%d", ntohs(cert.h.len) - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); if (2 < vflag && 4 < ntohs(cert.h.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(cert.h.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR)); + return NULL; } static u_char * @@@@ -821,13 +886,18 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)); + return NULL; } static u_char * @@@@ -838,13 +908,18 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)); + return NULL; } static u_char * @@@@ -855,13 +930,18 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" n len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)); + return NULL; } static u_char * @@@@ -904,6 +984,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_N)); p = (struct isakmp_pl_n *)ext; + TCHECK(*p); safememcpy(&n, ext, sizeof(n)); doi = ntohl(n.doi); proto = n.prot_id; @@@@ -913,7 +994,8 @@@@ printf(" type=%s", NOTIFYSTR(ntohs(n.type))); if (n.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), n.spi_size); + if (!rawprint((caddr_t)(p + 1), n.spi_size)) + goto trunc; } return (u_char *)(p + 1) + n.spi_size; } @@@@ -932,7 +1014,8 @@@@ printf(" type=%s", NOTIFYSTR(ntohs(n.type))); if (n.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), n.spi_size); + if (!rawprint((caddr_t)(p + 1), n.spi_size)) + goto trunc; } cp = (u_char *)(p + 1) + n.spi_size; @@@@ -969,6 +1052,9 @@@@ printf(")"); } return (u_char *)ext + ntohs(n.h.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N)); + return NULL; } static u_char * @@@@ -984,6 +1070,7 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_D)); p = (struct isakmp_pl_d *)ext; + TCHECK(*p); safememcpy(&d, ext, sizeof(d)); doi = ntohl(d.doi); proto = d.prot_id; @@@@ -1001,10 +1088,14 @@@@ for (i = 0; i < ntohs(d.num_spi); i++) { if (i != 0) printf(","); - rawprint((caddr_t)q, d.spi_size); + if (!rawprint((caddr_t)q, d.spi_size)) + goto trunc; q += d.spi_size; } return q; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D)); + return NULL; } static u_char * @@@@ -1015,13 +1106,18 @@@@ printf("%s:", NPSTR(ISAKMP_NPTYPE_VID)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID)); + return NULL; } static u_char * @@@@ -1033,6 +1129,7 @@@@ u_int item_len; cp = (u_char *)ext; + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); /* @@@@ -1056,6 +1153,9 @@@@ cp += item_len; } return cp; +trunc: + printf(" [|isakmp]"); + return NULL; } static u_char * @@@@ -1069,15 +1169,12 @@@@ cp = (u_char *)ext; while (np) { - TCHECK2(*ext, sizeof(e)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); - if (ep < (u_char *)ext + ntohs(e.len)) { - printf(" [|%s]", NPSTR(np)); - cp = ep + 1; - break; - } + TCHECK2(*ext, ntohs(e.len)); + depth++; printf("\n"); for (i = 0; i < depth; i++) @@@@ -1097,6 +1194,7 @@@@ } return cp; trunc: + printf(" [|%s]", NPSTR(np)); return NULL; } @ 1.1.6.2.2.3 log @correct spelling, align columns, and append new CAN identifiers to patch matrix @ text @d20 1 a20 1 tcpdump patch matrix; thl@@dev.de.cw.com d23 12 a34 12 OpenPKG 120 121 130 131 20040207 --- --- --- --- -------- CAN-2002-0380 nfs y n n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2002-1350 bgp y n n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2003-0108 isakmp y n n n n see past OpenPKG-SA-2003.014-tcpdump depth y y y n n (*) CAN-2003-0989 isakmp y y y n n updates CAN-2003-0108-isakmp CAN-2003-1029 l2tp y y n n n see past OpenPKG-SA-2004.002-tcpdump CAN-2004-0055 radius y y y y y see past OpenPKG-SA-2004.002-tcpdump CAN-2004-0057 isakmp y y y y y see past OpenPKG-SA-2004.002-tcpdump CAN-2004-0183 isakmp y y y y y CAN-2004-0184 isakmp y y y y y @ 1.1.4.1 log @Fix for CAN-2003-0108 security advisory. @ text @a0 59 --- tcpdump-3.7.1/print-isakmp.c 2001-10-26 05:41:29.000000000 +0200 +++ tcpdump-3.7.2/print-isakmp.c 2003-02-26 07:07:19.000000000 +0100 @@@@ -30,7 +30,7 @@@@ #ifndef lint static const char rcsid[] = - "@@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.29 2001/10/26 03:41:29 itojun Exp $ (LBL)"; + "@@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.29.2.2 2003/02/26 05:58:39 fenner Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@@@ -43,9 +43,6 @@@@ #include #include -struct mbuf; -struct rtentry; - #include #include @@@@ -1028,6 +1025,7 @@@@ { u_char *cp; struct isakmp_gen e; + u_int item_len; cp = (u_char *)ext; safememcpy(&e, ext, sizeof(e)); @@@@ -1036,7 +1034,16 @@@@ cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); else { printf("%s", NPSTR(np)); - cp += ntohs(e.len); + item_len = ntohs(e.len); + if (item_len == 0) { + /* + * We don't want to loop forever processing this + * bogus (zero-length) item; return NULL so that + * we stop dissecting. + */ + cp = NULL; + } else + cp += item_len; } return cp; } @@@@ -1069,6 +1076,11 @@@@ printf(")"); depth--; + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } + np = e.np; ext = (struct isakmp_gen *)cp; } @ 1.1.4.2 log @MFS: apply security patch (see OpenPKG-SA-2003.014-tcpdump); merge in OpenSSL DES fixes @ text @d1 8 a8 21 --- print-bgp.c Thu Oct 18 11:52:17 2001 +++ print-bgp.c Tue Mar 4 10:33:39 2003 @@@@ -469,11 +469,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; d10 13 a22 54 @@@@ -505,11 +513,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #endif @@@@ -598,6 +614,7 @@@@ printf(" (Withdrawn routes: %d bytes)", len); #else char buf[MAXHOSTNAMELEN + 100]; + int wpfx; TCHECK2(p[2], len); i = 2; @@@@ -605,7 +622,10 @@@@ printf(" (Withdrawn routes:"); while(i < 2 + len) { - i += decode_prefix4(&p[i], buf, sizeof(buf)); + wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); + if (wpfx < 0) + break; + i += wpfx; printf(" %s", buf); } printf(")\n"); @@@@ -666,9 +686,9 @@@@ while (dat + length > p) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); - printf(" %s", buf); if (i < 0) break; + printf(" %s", buf); p += i; } --- print-isakmp.c Fri Oct 26 05:41:29 2001 +++ print-isakmp.c Tue Mar 4 10:33:39 2003 @@@@ -1028,6 +1028,7 @@@@ d30 1 a30 1 @@@@ -1036,7 +1037,16 @@@@ d48 1 a48 2 @@@@ -1068,6 +1078,11 @@@@ cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto); d51 1 a51 1 + d56 1 a56 1 a58 24 --- print-nfs.c Sun Jul 8 10:01:43 2001 +++ print-nfs.c Tue Mar 4 10:33:39 2003 @@@@ -716,10 +716,16 @@@@ case NFSPROC_FSINFO: printf(" fsinfo"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_PATHCONF: printf(" pathconf"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_COMMIT: @@@@ -1027,7 +1033,6 @@@@ printf(" ERROR: %s", tok2str(status2str, "unk %d", errnum)); nfserr = 1; - return (NULL); a59 104 return (dp + 1); trunc: @@@@ -1109,8 +1114,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); return (parsefattr(dp, verbose, v3) != NULL); } @@@@ -1120,8 +1127,10 @@@@ { int er; - if (!(dp = parsestatus(dp, &er)) || er) + if (!(dp = parsestatus(dp, &er))) return (0); + if (er) + return (1); dp = parsefh(dp, 0); if (dp == NULL) @@@@ -1136,8 +1145,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return(0); + if (er) + return(1); if (v3 && !(dp = parse_post_op_attr(dp, vflag))) return (0); putchar(' '); @@@@ -1151,8 +1162,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || (!v3 && er)) + if (dp == NULL) return (0); + if (!v3 && er) + return (1); if (qflag) return(1); @@@@ -1164,7 +1177,7 @@@@ return (0); } - TCHECK2(dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); + TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); sfsp = (const struct nfs_statfs *)dp; @@@@ -1205,8 +1218,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); if (qflag) return (1); @@@@ -1242,7 +1257,7 @@@@ if (!ntohl(dp[0])) return (dp + 1); dp++; - TCHECK2(dp, 24); + TCHECK2(*dp, 24); if (verbose > 1) { return parse_wcc_attr(dp); } else { @@@@ -1379,9 +1394,9 @@@@ (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_sec), (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_nsec)); } - return (0); -trunc: return (1); +trunc: + return (0); } static int @@@@ -1409,9 +1424,9 @@@@ ntohl(spp->pc_chownrestricted) ? "chownres" : "", ntohl(spp->pc_caseinsensitive) ? "igncase" : "", ntohl(spp->pc_casepreserving) ? "keepcase" : ""); - return (0); -trunc: return (1); +trunc: + return (0); } static void @ 1.1.4.3 log @clear patch to enhance readability of next update commit @ text @d1 242 @ 1.1.4.4 log @SA-2004.002-tcpdump; CAN-2002-0380, CAN-2002-1350, CAN-2003-0108, CAN-2003-0989, CAN-2003-1029, CAN-2004-0055, CAN-2004-0057 @ text @a0 766 tcpdump patch patrix; thl@@dev.de.cw.com tcpdump 371 371 372 381 OpenPKG 120 121 130 20020822 --- --- --- --- CAN-2002-0380 nfs y n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2002-1350 bgp y n n n see past OpenPKG-SA-2003.014-tcpdump CAN-2003-0108 isakmp y n n n see past OpenPKG-SA-2003.014-tcpdump depth y y y n (*) CAN-2003-0989 isakmp y y y n updates CAN-2003-0108-isakmp CAN-2003-1029 l2tp y y n n CAN-2004-0055 radius y y y y CAN-2004-0057 isakmp y y y y (*) the vendor code fix for CAN-2003-0108 had two other unrelated code changes piggybacked. We removed the cosmetics (constify) and extracted an enhancement (depth). http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2002-0380 (nfs) Buffer overflow in tcpdump 3.6.2 and earlier allows remote attackers to cause a denial of service and possibly execute arbitrary code via an NFS packet. --- print-nfs.c.CAN-2002-0380 Sun Jul 8 10:01:43 2001 +++ print-nfs.c Tue Mar 4 10:33:39 2003 @@@@ -716,10 +716,16 @@@@ case NFSPROC_FSINFO: printf(" fsinfo"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_PATHCONF: printf(" pathconf"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_COMMIT: @@@@ -1027,7 +1033,6 @@@@ printf(" ERROR: %s", tok2str(status2str, "unk %d", errnum)); nfserr = 1; - return (NULL); } return (dp + 1); trunc: @@@@ -1109,8 +1114,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); return (parsefattr(dp, verbose, v3) != NULL); } @@@@ -1120,8 +1127,10 @@@@ { int er; - if (!(dp = parsestatus(dp, &er)) || er) + if (!(dp = parsestatus(dp, &er))) return (0); + if (er) + return (1); dp = parsefh(dp, 0); if (dp == NULL) @@@@ -1136,8 +1145,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return(0); + if (er) + return(1); if (v3 && !(dp = parse_post_op_attr(dp, vflag))) return (0); putchar(' '); @@@@ -1151,8 +1162,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || (!v3 && er)) + if (dp == NULL) return (0); + if (!v3 && er) + return (1); if (qflag) return(1); @@@@ -1164,7 +1177,7 @@@@ return (0); } - TCHECK2(dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); + TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); sfsp = (const struct nfs_statfs *)dp; @@@@ -1205,8 +1218,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); if (qflag) return (1); @@@@ -1242,7 +1257,7 @@@@ if (!ntohl(dp[0])) return (dp + 1); dp++; - TCHECK2(dp, 24); + TCHECK2(*dp, 24); if (verbose > 1) { return parse_wcc_attr(dp); } else { @@@@ -1379,9 +1394,9 @@@@ (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_sec), (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_nsec)); } - return (0); -trunc: return (1); +trunc: + return (0); } static int @@@@ -1409,9 +1424,9 @@@@ ntohl(spp->pc_chownrestricted) ? "chownres" : "", ntohl(spp->pc_caseinsensitive) ? "igncase" : "", ntohl(spp->pc_casepreserving) ? "keepcase" : ""); - return (0); -trunc: return (1); +trunc: + return (0); } static void http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2002-1350 (bgp) The BGP decoding routines in tcpdump before 3.6.2-2.2 do not properly copy data, which allows remote attackers to cause a denial of service and possibly execute arbitrary code. --- print-bgp.c.CAN-2002-1350 Thu Oct 18 11:52:17 2001 +++ print-bgp.c Tue Mar 4 10:33:39 2003 @@@@ -469,11 +469,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #endif @@@@ -505,11 +513,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #endif @@@@ -598,6 +614,7 @@@@ printf(" (Withdrawn routes: %d bytes)", len); #else char buf[MAXHOSTNAMELEN + 100]; + int wpfx; TCHECK2(p[2], len); i = 2; @@@@ -605,7 +622,10 @@@@ printf(" (Withdrawn routes:"); while(i < 2 + len) { - i += decode_prefix4(&p[i], buf, sizeof(buf)); + wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); + if (wpfx < 0) + break; + i += wpfx; printf(" %s", buf); } printf(")\n"); @@@@ -666,9 +686,9 @@@@ while (dat + length > p) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); - printf(" %s", buf); if (i < 0) break; + printf(" %s", buf); p += i; } http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0108 (isakmp) sakmp_sub_print in tcpdump 3.6 through 3.7.1 allows remote attackers to cause a denial of service (CPU consumption) via a certain malformed ISAKMP packet to UDP port 500, which causes tcpdump to enter an infinite loop. --- print-isakmp.c.CAN-2003-0108 Fri Oct 26 05:41:29 2001 +++ print-isakmp.c Tue Mar 4 10:33:39 2003 @@@@ -1028,6 +1028,7 @@@@ { u_char *cp; struct isakmp_gen e; + u_int item_len; cp = (u_char *)ext; safememcpy(&e, ext, sizeof(e)); @@@@ -1036,7 +1037,16 @@@@ cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); else { printf("%s", NPSTR(np)); - cp += ntohs(e.len); + item_len = ntohs(e.len); + if (item_len == 0) { + /* + * We don't want to loop forever processing this + * bogus (zero-length) item; return NULL so that + * we stop dissecting. + */ + cp = NULL; + } else + cp += item_len; } return cp; } @@@@ -1068,6 +1078,11 @@@@ cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto); printf(")"); depth--; + + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } np = e.np; ext = (struct isakmp_gen *)cp; http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0108 (depth) Not directly related to the CVE security topic but piggybacked. revision 1.34 date: 2002/09/05 00:43:21; author: guy; state: Exp; lines: +155 -127 1.) print-isakmp.c: Constify. [undone to reduce patch] 2.) [real security issue as of CAN-2003-0108] 3.) Have "isakmp_sub_print()" take the depth as an argument, rather than have it as a static variable, for cleanliness. Index: print-isakmp.c --- print-isakmp.c.CAN-2003-0108 2004-01-15 16:30:04.000000000 +0100 +++ print-isakmp.c 2004-01-15 16:31:28.000000000 +0100 @@@@ -67,36 +67,36 @@@@ #define sockaddr_storage sockaddr #endif -static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); +static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); static u_char *isakmp_p_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_t_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_ke_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_id_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_cert_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_cr_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_sig_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); -static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); -static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); +static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); +static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); static u_char *isakmp_n_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_d_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); static u_char *isakmp_vid_print(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t); -static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); -static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *, - u_int32_t, u_int32_t, u_int32_t); + u_int32_t, u_int32_t, int); +static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); +static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *, u_int32_t, + u_int32_t, u_int32_t, int); static char *numstr(int); static void safememcpy(void *, void *, size_t); @@@@ -121,7 +121,7 @@@@ /* isakmp->np */ static u_char *(*npfunc[])(struct isakmp_gen *, u_char *, u_int32_t, - u_int32_t, u_int32_t) = { + u_int32_t, u_int32_t, int) = { NULL, isakmp_sa_print, isakmp_p_print, @@@@ -333,7 +333,7 @@@@ rawprint(caddr_t loc, size_t len) { static u_char *p; - int i; + size_t i; p = (u_char *)loc; for (i = 0; i < len; i++) @@@@ -342,7 +342,7 @@@@ struct attrmap { char *type; - int nvalue; + u_int nvalue; char *value[30]; /*XXX*/ }; @@@@ -418,7 +418,7 @@@@ static u_char * isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_sa *p, sa; u_int32_t *q; @@@@ -462,14 +462,14 @@@@ ext = (struct isakmp_gen *)np; - cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0); + cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, depth); return cp; } static u_char * isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_p *p, prop; u_char *cp; @@@@ -488,7 +488,7 @@@@ ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, - prop.prot_id); + prop.prot_id, depth); return cp; } @@@@ -551,7 +551,7 @@@@ static u_char * isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_pl_t *p, t; u_char *cp; @@@@ -613,7 +613,7 @@@@ static u_char * isakmp_ke_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -630,7 +630,7 @@@@ static u_char * isakmp_id_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { #define USE_IPSECDOI_IN_PHASE1 1 struct isakmp_pl_id *p, id; @@@@ -766,7 +766,7 @@@@ static u_char * isakmp_cert_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_cert *p, cert; static char *certstr[] = { @@@@ -790,7 +790,7 @@@@ static u_char * isakmp_cr_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_cert *p, cert; static char *certstr[] = { @@@@ -814,7 +814,7 @@@@ static u_char * isakmp_hash_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -831,7 +831,7 @@@@ static u_char * isakmp_sig_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -848,7 +848,7 @@@@ static u_char * isakmp_nonce_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -865,7 +865,7 @@@@ static u_char * isakmp_n_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_n *p, n; u_char *cp; @@@@ -955,8 +955,9 @@@@ (*(u_int32_t *)cp) ? "en" : "dis"); break; case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: - isakmp_sub_print(ISAKMP_NPTYPE_SA, - (struct isakmp_gen *)cp, ep, phase, doi, proto); + if (isakmp_sub_print(ISAKMP_NPTYPE_SA, + (struct isakmp_gen *)cp, ep, phase, doi, proto, depth) == NULL) + return NULL; break; default: /* NULL is dummy */ @@@@ -971,7 +972,7 @@@@ static u_char * isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0) + u_int32_t doi0, u_int32_t proto0, int depth) { struct isakmp_pl_d *p, d; u_int8_t *q; @@@@ -1007,7 +1008,7 @@@@ static u_char * isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, - u_int32_t doi, u_int32_t proto) + u_int32_t doi, u_int32_t proto, int depth) { struct isakmp_gen e; @@@@ -1024,7 +1025,7 @@@@ static u_char * isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep, - u_int32_t phase, u_int32_t doi, u_int32_t proto) + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) { u_char *cp; struct isakmp_gen e; @@@@ -1053,10 +1053,9 @@@@ static u_char * isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep, - u_int32_t phase, u_int32_t doi, u_int32_t proto) + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) { u_char *cp; - static int depth = 0; int i; struct isakmp_gen e; @@@@ -1075,7 +1080,7 @@@@ for (i = 0; i < depth; i++) printf(" "); printf("("); - cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto); + cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto, depth); printf(")"); depth--; @@@@ -1180,35 +1185,36 @@@@ printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "", base.flags & ISAKMP_FLAG_C ? "C" : ""); } - printf(":"); - { - struct isakmp_gen *ext; - int nparen; + if (vflag) { + struct isakmp_gen *ext; + int nparen; #define CHECKLEN(p, np) \ - if (ep < (u_char *)(p)) { \ - printf(" [|%s]", NPSTR(np)); \ - goto done; \ - } + if (ep < (u_char *)(p)) { \ + printf(" [|%s]", NPSTR(np)); \ + goto done; \ + } - /* regardless of phase... */ - if (base.flags & ISAKMP_FLAG_E) { - /* - * encrypted, nothing we can do right now. - * we hope to decrypt the packet in the future... - */ - printf(" [encrypted %s]", NPSTR(base.np)); - goto done; - } + printf(":"); - nparen = 0; - CHECKLEN(p + 1, base.np) + /* regardless of phase... */ + if (base.flags & ISAKMP_FLAG_E) { + /* + * encrypted, nothing we can do right now. + * we hope to decrypt the packet in the future... + */ + printf(" [encrypted %s]", NPSTR(base.np)); + goto done; + } - np = base.np; - ext = (struct isakmp_gen *)(p + 1); - isakmp_sub_print(np, ext, ep, phase, 0, 0); - } + nparen = 0; + CHECKLEN(p + 1, base.np) + + np = base.np; + ext = (struct isakmp_gen *)(p + 1); + isakmp_sub_print(np, ext, ep, phase, 0, 0, 0); + } done: if (vflag) { http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0989 (isakmp) tcpdump before 3.8.1 allows remote attackers to cause a denial of service (infinite loop) via certain ISAKMP packets, a different vulnerability than CAN-2004-0057. Index: print-isakmp.c --- print-isakmp.c.CAN-2003-0989 2004-01-15 16:30:04.000000000 +0100 +++ print-isakmp.c 2004-01-15 16:31:28.000000000 +0100 @@@@ -1033,20 +1034,25 @@@@ cp = (u_char *)ext; safememcpy(&e, ext, sizeof(e)); - if (NPFUNC(np)) - cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); - else { + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + return NULL; + + if (NPFUNC(np)) { + /* + * XXX - what if item_len is too short, or too long, + * for this payload type? + */ + cp = (*NPFUNC(np))(ext, ep, phase, doi, proto, depth); + } else { printf("%s", NPSTR(np)); - item_len = ntohs(e.len); - if (item_len == 0) { - /* - * We don't want to loop forever processing this - * bogus (zero-length) item; return NULL so that - * we stop dissecting. - */ - cp = NULL; - } else - cp += item_len; + cp += item_len; } return cp; } http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-1029 (l2tp) The L2TP protocol parser in tcpdump 3.8.1 and earlier allows remote attackers to cause a denial of service (infinite loop and memory consumption) via a packet with invalid data to UDP port 1701, which causes l2tp_avp_print to use a bad length value when calling print_octets. diff -u -d -u -d -r1.16 -r1.17 --- print-l2tp.c.CAN-2003-1029 16 Nov 2003 09:36:26 -0000 1.16 +++ print-l2tp.c 26 Dec 2003 23:20:58 -0000 1.17 @@@@ -474,8 +474,17 @@@@ TCHECK(*ptr); /* Flags & Length */ len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK; - /* If it is not long enough to decode the entire AVP, we'll - abandon. */ + /* If it is not long enough to contain the header, we'll give up. */ + if (len < 6) + goto trunc; + + /* If it goes past the end of the remaining length of the packet, + we'll give up. */ + if (len > (u_int)length) + goto trunc; + + /* If it goes past the end of the remaining length of the captured + data, we'll give up. */ TCHECK2(*ptr, len); /* After this point, no need to worry about truncation */ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0055 (radius) The print_attr_string function in print-radius.c for tcpdump 3.8.1 and earlier allows remote attackers to cause a denial of service (segmentation fault) via a RADIUS attribute with a large length value. Index: print-radius.c =================================================================== RCS file: /tcpdump/master/tcpdump/print-radius.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -u -d -r1.23 -r1.24 --- print-radius.c.CAN-2004-0055 15 Dec 2003 13:52:15 -0000 1.23 +++ print-radius.c 7 Jan 2004 08:00:52 -0000 1.24 @@@@ -476,7 +476,7 @@@@ break; } - for (i=0; i < length ; i++, data++) + for (i=0; *data && i < length ; i++, data++) printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); return; http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0057 (isakmp) The rawprint function in the ISAKMP decoding routines (print-isakmp.c) for tcpdump 3.8.1 and earlier allows remote attackers to cause a denial of service (segmentation fault) via malformed ISAKMP packets that cause invalid "len" or "loc" values to be used in a loop, a different vulnerability than CAN-2003-0989. Index: print-isakmp.c =================================================================== RCS file: /tcpdump/master/tcpdump/print-isakmp.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -u -d -r1.41 -r1.42 --- print-isakmp.c.CAN-2004-0057 20 Dec 2003 10:03:19 -0000 1.41 +++ print-isakmp.c 7 Jan 2004 08:00:51 -0000 1.42 @@@@ -327,9 +327,13 @@@@ static u_char *p; size_t i; + TCHECK2(*loc, len); + p = (u_char *)loc; for (i = 0; i < len; i++) printf("%02x", p[i] & 0xff); +trunc: + return; } struct attrmap { @@@@ -1111,6 +1115,8 @@@@ cp = (const u_char *)ext; while (np) { + TCHECK2(*ext, sizeof(e)); + safememcpy(&e, ext, sizeof(e)); if (ep < (u_char *)ext + ntohs(e.len)) { @@@@ -1136,6 +1142,8 @@@@ ext = (struct isakmp_gen *)cp; } return cp; +trunc: + return NULL; } static char * @ 1.1.2.1 log @Fix for CAN-2003-0108. @ text @a0 59 --- tcpdump-3.7.1/print-isakmp.c 2001-10-26 05:41:29.000000000 +0200 +++ tcpdump-3.7.2/print-isakmp.c 2003-02-26 07:07:19.000000000 +0100 @@@@ -30,7 +30,7 @@@@ #ifndef lint static const char rcsid[] = - "@@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.29 2001/10/26 03:41:29 itojun Exp $ (LBL)"; + "@@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.29.2.2 2003/02/26 05:58:39 fenner Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@@@ -43,9 +43,6 @@@@ #include #include -struct mbuf; -struct rtentry; - #include #include @@@@ -1028,6 +1025,7 @@@@ { u_char *cp; struct isakmp_gen e; + u_int item_len; cp = (u_char *)ext; safememcpy(&e, ext, sizeof(e)); @@@@ -1036,7 +1034,16 @@@@ cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); else { printf("%s", NPSTR(np)); - cp += ntohs(e.len); + item_len = ntohs(e.len); + if (item_len == 0) { + /* + * We don't want to loop forever processing this + * bogus (zero-length) item; return NULL so that + * we stop dissecting. + */ + cp = NULL; + } else + cp += item_len; } return cp; } @@@@ -1069,6 +1076,11 @@@@ printf(")"); depth--; + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } + np = e.np; ext = (struct isakmp_gen *)cp; } @ 1.1.2.2 log @MFC: apply corrected security patch (see OpenPKG-SA-2003.014-tcpdump) @ text @d1 8 a8 21 --- print-bgp.c Thu Oct 18 11:52:17 2001 +++ print-bgp.c Tue Mar 4 10:33:39 2003 @@@@ -469,11 +469,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; d10 13 a22 54 @@@@ -505,11 +513,19 @@@@ switch (af) { case AFNUM_INET: advance = decode_prefix4(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #ifdef INET6 case AFNUM_INET6: advance = decode_prefix6(p, buf, sizeof(buf)); + if (advance < 0) { + p = dat + len; + break; + } printf(" %s", buf); break; #endif @@@@ -598,6 +614,7 @@@@ printf(" (Withdrawn routes: %d bytes)", len); #else char buf[MAXHOSTNAMELEN + 100]; + int wpfx; TCHECK2(p[2], len); i = 2; @@@@ -605,7 +622,10 @@@@ printf(" (Withdrawn routes:"); while(i < 2 + len) { - i += decode_prefix4(&p[i], buf, sizeof(buf)); + wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); + if (wpfx < 0) + break; + i += wpfx; printf(" %s", buf); } printf(")\n"); @@@@ -666,9 +686,9 @@@@ while (dat + length > p) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); - printf(" %s", buf); if (i < 0) break; + printf(" %s", buf); p += i; } --- print-isakmp.c Fri Oct 26 05:41:29 2001 +++ print-isakmp.c Tue Mar 4 10:33:39 2003 @@@@ -1028,6 +1028,7 @@@@ d30 1 a30 1 @@@@ -1036,7 +1037,16 @@@@ d48 1 a48 2 @@@@ -1068,6 +1078,11 @@@@ cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto); d51 1 a51 1 + d56 1 a56 1 a58 24 --- print-nfs.c Sun Jul 8 10:01:43 2001 +++ print-nfs.c Tue Mar 4 10:33:39 2003 @@@@ -716,10 +716,16 @@@@ case NFSPROC_FSINFO: printf(" fsinfo"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_PATHCONF: printf(" pathconf"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; break; case NFSPROC_COMMIT: @@@@ -1027,7 +1033,6 @@@@ printf(" ERROR: %s", tok2str(status2str, "unk %d", errnum)); nfserr = 1; - return (NULL); a59 104 return (dp + 1); trunc: @@@@ -1109,8 +1114,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); return (parsefattr(dp, verbose, v3) != NULL); } @@@@ -1120,8 +1127,10 @@@@ { int er; - if (!(dp = parsestatus(dp, &er)) || er) + if (!(dp = parsestatus(dp, &er))) return (0); + if (er) + return (1); dp = parsefh(dp, 0); if (dp == NULL) @@@@ -1136,8 +1145,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return(0); + if (er) + return(1); if (v3 && !(dp = parse_post_op_attr(dp, vflag))) return (0); putchar(' '); @@@@ -1151,8 +1162,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || (!v3 && er)) + if (dp == NULL) return (0); + if (!v3 && er) + return (1); if (qflag) return(1); @@@@ -1164,7 +1177,7 @@@@ return (0); } - TCHECK2(dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); + TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); sfsp = (const struct nfs_statfs *)dp; @@@@ -1205,8 +1218,10 @@@@ int er; dp = parsestatus(dp, &er); - if (dp == NULL || er) + if (dp == NULL) return (0); + if (er) + return (1); if (qflag) return (1); @@@@ -1242,7 +1257,7 @@@@ if (!ntohl(dp[0])) return (dp + 1); dp++; - TCHECK2(dp, 24); + TCHECK2(*dp, 24); if (verbose > 1) { return parse_wcc_attr(dp); } else { @@@@ -1379,9 +1394,9 @@@@ (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_sec), (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_nsec)); } - return (0); -trunc: return (1); +trunc: + return (0); } static int @@@@ -1409,9 +1424,9 @@@@ ntohl(spp->pc_chownrestricted) ? "chownres" : "", ntohl(spp->pc_caseinsensitive) ? "igncase" : "", ntohl(spp->pc_casepreserving) ? "keepcase" : ""); - return (0); -trunc: return (1); +trunc: + return (0); } static void @