commit cb922d07cce6574874b954555ebad4338748087b
Author: Francois-Xavier Le Bail <fx.lebail@yahoo.com>
Date:   Tue Nov 17 17:12:22 2015 +0100

    CVE-2016-7934,7935,7937/RTP: Fix two segmentation faults
    
    Add two test files for these fixes.
    Add more bounds checks in VAT, RTP and RTCP printers.
    
    Moreover:
    Add and use *_tstr[] strings.
    Update the output of a test accordingly.
    Remove spaces before tabs.

Index: tcpdump-3.9.8/print-udp.c
===================================================================
--- tcpdump-3.9.8.orig/print-udp.c
+++ tcpdump-3.9.8/print-udp.c
@@ -110,16 +110,25 @@ static void
 vat_print(const void *hdr, register const struct udphdr *up)
 {
 	/* vat/vt audio */
-	u_int ts = *(u_int16_t *)hdr;
+	u_int ts;
+
+	TCHECK_16BITS((const u_int *)hdr);
+	ts = EXTRACT_16BITS(hdr); 
 	if ((ts & 0xf060) != 0) {
 		/* probably vt */
+		TCHECK_16BITS(&up->uh_ulen);
 		(void)printf("udp/vt %u %d / %d",
 			     (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)),
 			     ts & 0x3ff, ts >> 10);
 	} else {
 		/* probably vat */
-		u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]);
-		u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]);
+		uint32_t i0, i1;
+
+		TCHECK_32BITS(&((const u_int *)hdr)[0]); 
+		i0 = EXTRACT_32BITS(&((const u_int *)hdr)[0]);
+		TCHECK_32BITS(&((const u_int *)hdr)[1]);
+		i1 = EXTRACT_32BITS(&((const u_int *)hdr)[1]);
+		TCHECK_16BITS(&up->uh_ulen);
 		printf("udp/vat %u c%d %u%s",
 			(u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8),
 			i0 & 0xffff,
@@ -130,6 +139,9 @@ vat_print(const void *hdr, register cons
 		if (i0 & 0x3f000000)
 			printf(" s%d", (i0 >> 24) & 0x3f);
 	}
+
+trunc:
+	printf("%s", " [|vat]");
 }
 
 static void
@@ -137,12 +149,16 @@ rtp_print(const void *hdr, u_int len, re
 {
 	/* rtp v1 or v2 */
 	u_int *ip = (u_int *)hdr;
-	u_int hasopt, hasext, contype, hasmarker;
-	u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]);
-	u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]);
-	u_int dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8;
+	u_int hasopt, hasext, contype, hasmarker, dlen;
+	uint32_t i0, i1;
 	const char * ptype;
 
+	TCHECK_32BITS(&((const u_int *)hdr)[0]);
+	i0 = EXTRACT_32BITS(&((const u_int *)hdr)[0]);
+	TCHECK_32BITS(&((const u_int *)hdr)[1]);
+	i1 = EXTRACT_32BITS(&((const u_int *)hdr)[1]); 
+	TCHECK_16BITS(&up->uh_ulen);
+	dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8;
 	ip += 2;
 	len >>= 2;
 	len -= 2;
@@ -173,10 +189,12 @@ rtp_print(const void *hdr, u_int len, re
 		i0 & 0xffff,
 		i1);
 	if (vflag) {
+		TCHECK_32BITS(&((const u_int *)hdr)[2]);
 		printf(" %u", EXTRACT_32BITS(&((u_int *)hdr)[2]));
 		if (hasopt) {
 			u_int i2, optlen;
 			do {
+				TCHECK2(*ip, 4);
 				i2 = ip[0];
 				optlen = (i2 >> 16) & 0xff;
 				if (optlen == 0 || optlen > len) {
@@ -189,6 +207,7 @@ rtp_print(const void *hdr, u_int len, re
 		}
 		if (hasext) {
 			u_int i2, extlen;
+			TCHECK2(*ip, 4);
 			i2 = ip[0];
 			extlen = (i2 & 0xffff) + 1;
 			if (extlen > len) {
@@ -197,9 +216,13 @@ rtp_print(const void *hdr, u_int len, re
 			}
 			ip += extlen;
 		}
+		TCHECK(*ip); 
 		if (contype == 0x1f) /*XXX H.261 */
 			printf(" 0x%04x", ip[0] >> 16);
 	}
+
+ trunc:
+	printf("%s", " [|rtp]");
 }
 
 static const u_char *
@@ -213,10 +236,9 @@ rtcp_print(const u_char *hdr, const u_ch
 	u_int16_t flags;
 	int cnt;
 	double ts, dts;
-	if ((u_char *)(rh + 1) > ep) {
-		printf(" [|rtcp]");
-		return (ep);
-	}
+	if ((const u_char *)(rh + 1) > ep)
+		goto trunc; 
+	TCHECK(*rh);
 	len = (EXTRACT_16BITS(&rh->rh_len) + 1) * 4;
 	flags = EXTRACT_16BITS(&rh->rh_flags);
 	cnt = (flags >> 8) & 0x1f;
@@ -228,10 +250,9 @@ rtcp_print(const u_char *hdr, const u_ch
 			printf(" [%d]", len);
 		if (vflag)
 			printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
-		if ((u_char *)(sr + 1) > ep) {
-			printf(" [|rtcp]");
-			return (ep);
-		}
+		if ((const u_char *)(sr + 1) > ep) 
+			goto trunc;
+		TCHECK(*sr); 
 		ts = (double)(EXTRACT_32BITS(&sr->sr_ntp.upper)) +
 		    ((double)(EXTRACT_32BITS(&sr->sr_ntp.lower)) /
 		    4294967296.0);
@@ -267,10 +288,9 @@ rtcp_print(const u_char *hdr, const u_ch
 	if (cnt > 1)
 		printf(" c%d", cnt);
 	while (--cnt >= 0) {
-		if ((u_char *)(rr + 1) > ep) {
-			printf(" [|rtcp]");
-			return (ep);
-		}
+		if ((const u_char *)(rr + 1) > ep) 
+			goto trunc;
+		TCHECK(*rr);
 		if (vflag)
 			printf(" %u", EXTRACT_32BITS(&rr->rr_srcid));
 		ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.;
@@ -281,6 +301,10 @@ rtcp_print(const u_char *hdr, const u_ch
 		    EXTRACT_32BITS(&rr->rr_dv), ts, dts);
 	}
 	return (hdr + len);
+
+trunc:
+	printf("%s", " [|rtcp]");
+	return ep;
 }
 
 static int udp_cksum(register const struct ip *ip,
@@ -413,6 +437,10 @@ udpipaddr_print(const struct ip *ip, int
 			}
 		}
 	}
+	return;
+
+trunc:
+	printf("%s", " [|udp]");
 }
 
 void
