Skip to content

Commit 66df248

Browse files
guyharrisinfrastation
authored andcommitted
CVE-2017-12985/IPv6: Check for print routines returning -1 when running past the end.
rt6_print(), ah_print(), and esp_print() return -1 if they run up against the end of the packet while dissecting; if that happens, stop dissecting, don't try to fetch the next header value, because 1) *it* might be past the end of the packet and 2) we won't be using it in any case, as we'll be exiting the loop. Also, change mobility_print() to return -1 if it runs up against the end of the packet, and stop dissecting if it does so. This fixes a buffer over-read discovered by Brian 'geeknik' Carpenter. Add tests using the capture files supplied by the reporter(s).
1 parent 0318fa8 commit 66df248

7 files changed

+16
-1
lines changed

Diff for: print-ip6.c

+11
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
280280
advance = sizeof(struct ip6_hdr);
281281
nh = ip6->ip6_nxt;
282282
while (cp < ndo->ndo_snapend && advance > 0) {
283+
if (len < (u_int)advance)
284+
goto trunc;
283285
cp += advance;
284286
len -= advance;
285287

@@ -322,10 +324,15 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
322324
* mobility header.
323325
*/
324326
advance = mobility_print(ndo, cp, (const u_char *)ip6);
327+
if (advance < 0)
328+
return;
325329
nh = *cp;
326330
return;
327331
case IPPROTO_ROUTING:
332+
ND_TCHECK(*cp);
328333
advance = rt6_print(ndo, cp, (const u_char *)ip6);
334+
if (advance < 0)
335+
return;
329336
nh = *cp;
330337
break;
331338
case IPPROTO_SCTP:
@@ -345,12 +352,16 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
345352
return;
346353
case IPPROTO_AH:
347354
advance = ah_print(ndo, cp);
355+
if (advance < 0)
356+
return;
348357
nh = *cp;
349358
break;
350359
case IPPROTO_ESP:
351360
{
352361
int enh, padlen;
353362
advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
363+
if (advance < 0)
364+
return;
354365
nh = enh & 0xff;
355366
len -= padlen;
356367
break;

Diff for: print-mobility.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,5 +332,5 @@ mobility_print(netdissect_options *ndo,
332332

333333
trunc:
334334
ND_PRINT((ndo, "%s", tstr));
335-
return(mhlen);
335+
return(-1);
336336
}

Diff for: tests/TESTLIST

+2
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ otv-heapoverflow-1 otv-heapoverflow-1.pcap otv-heapoverflow-1.out -c10
432432
otv-heapoverflow-2 otv-heapoverflow-2.pcap otv-heapoverflow-2.out -c10
433433
q933-heapoverflow-2 q933-heapoverflow-2.pcap q933-heapoverflow-2.out
434434
atm-heapoverflow atm-heapoverflow.pcap atm-heapoverflow.out -c1 -e
435+
ipv6-next-header-oobr-1 ipv6-next-header-oobr-1.pcap ipv6-next-header-oobr-1.out
436+
ipv6-next-header-oobr-2 ipv6-next-header-oobr-2.pcap ipv6-next-header-oobr-2.out
435437

436438
# bad packets from Kamil Frankowicz
437439
snmp-heapoverflow-1 snmp-heapoverflow-1.pcap snmp-heapoverflow-1.out

Diff for: tests/ipv6-next-header-oobr-1.out

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
IP6 3030:3030:3030:3030:3030:3030:3030:3030 > 3030:3030:3030:3030:3030:3030:3030:3030: HBH [|ip6]

Diff for: tests/ipv6-next-header-oobr-1.pcap

88 Bytes
Binary file not shown.

Diff for: tests/ipv6-next-header-oobr-2.out

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
IP6 3030:3030:3030:3030:3030:3030:3030:3030 > 3030:3030:3030:3030:3030:3030:3030:3030: HBH [|AH]

Diff for: tests/ipv6-next-header-oobr-2.pcap

88 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)