Skip to content

Commit b20e163

Browse files
guyharrisinfrastation
authored andcommitted
CVE-2017-13026/IS-IS: Clean up processing of subTLVs.
Add bounds checks, do a common check to make sure we captured the entire subTLV, add checks to make sure the subTLV fits within the TLV. This fixes a buffer over-read discovered by Bhargava Shastry, SecT/TU Berlin. Add tests using the capture files supplied by the reporter(s), modified so the capture files won't be rejected as an invalid capture. Update existing tests for changes to IS-IS dissector.
1 parent 2e1f6d9 commit b20e163

13 files changed

+145
-246
lines changed

Diff for: print-isoclns.c

+37-15
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,7 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
14031403

14041404
while (len > 2)
14051405
{
1406+
ND_TCHECK2(*tptr, 2);
14061407
stlv_type = *(tptr++);
14071408
stlv_len = *(tptr++);
14081409

@@ -1415,11 +1416,18 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
14151416
/*len -= TLV_TYPE_LEN_OFFSET;*/
14161417
len = len -2;
14171418

1419+
/* Make sure the subTLV fits within the space left */
1420+
if (len < stlv_len)
1421+
goto trunc;
1422+
/* Make sure the entire subTLV is in the captured data */
1423+
ND_TCHECK2(*(tptr), stlv_len);
1424+
14181425
switch (stlv_type)
14191426
{
14201427
case ISIS_SUBTLV_SPB_MCID:
14211428
{
1422-
ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN);
1429+
if (stlv_len < ISIS_SUBTLV_SPB_MCID_MIN_LEN)
1430+
goto trunc;
14231431

14241432
subtlv_spb_mcid = (const struct isis_subtlv_spb_mcid *)tptr;
14251433

@@ -1434,15 +1442,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
14341442

14351443
/*tptr += SPB_MCID_MIN_LEN;
14361444
len -= SPB_MCID_MIN_LEN; */
1437-
tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
1438-
len = len - sizeof(struct isis_subtlv_spb_mcid);
1445+
tptr = tptr + ISIS_SUBTLV_SPB_MCID_MIN_LEN;
1446+
len = len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
1447+
stlv_len = stlv_len - ISIS_SUBTLV_SPB_MCID_MIN_LEN;
14391448

14401449
break;
14411450
}
14421451

14431452
case ISIS_SUBTLV_SPB_DIGEST:
14441453
{
1445-
ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN);
1454+
if (stlv_len < ISIS_SUBTLV_SPB_DIGEST_MIN_LEN)
1455+
goto trunc;
14461456

14471457
ND_PRINT((ndo, "\n\t RES: %d V: %d A: %d D: %d",
14481458
(*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
@@ -1461,18 +1471,15 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
14611471
}
14621472

14631473
len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
1474+
stlv_len = stlv_len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
14641475

14651476
break;
14661477
}
14671478

14681479
case ISIS_SUBTLV_SPB_BVID:
14691480
{
1470-
ND_TCHECK2(*(tptr), stlv_len);
1471-
1472-
while (len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
1481+
while (stlv_len >= ISIS_SUBTLV_SPB_BVID_MIN_LEN)
14731482
{
1474-
ND_TCHECK2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN);
1475-
14761483
ND_PRINT((ndo, "\n\t ECT: %08x",
14771484
EXTRACT_32BITS(tptr)));
14781485

@@ -1485,14 +1492,17 @@ isis_print_mt_port_cap_subtlv(netdissect_options *ndo,
14851492

14861493
tptr = tptr + 2;
14871494
len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
1495+
stlv_len = stlv_len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
14881496
}
14891497

14901498
break;
14911499
}
14921500

14931501
default:
1494-
break;
1502+
break;
14951503
}
1504+
tptr += stlv_len;
1505+
len -= stlv_len;
14961506
}
14971507

14981508
return 0;
@@ -1511,6 +1521,7 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
15111521

15121522
while (len > 2)
15131523
{
1524+
ND_TCHECK2(*tptr, 2);
15141525
stlv_type = *(tptr++);
15151526
stlv_len = *(tptr++);
15161527

@@ -1522,11 +1533,17 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
15221533

15231534
len = len - 2;
15241535

1536+
/* Make sure the subTLV fits within the space left */
1537+
if (len < stlv_len)
1538+
goto trunc;
1539+
/* Make sure the entire subTLV is in the captured data */
1540+
ND_TCHECK2(*(tptr), stlv_len);
1541+
15251542
switch (stlv_type)
15261543
{
15271544
case ISIS_SUBTLV_SPB_INSTANCE:
1528-
1529-
ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN);
1545+
if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN)
1546+
goto trunc;
15301547

15311548
ND_PRINT((ndo, "\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr)));
15321549
tptr = tptr+4;
@@ -1548,10 +1565,12 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
15481565
tmp = *(tptr++);
15491566

15501567
len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
1568+
stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
15511569

15521570
while (tmp)
15531571
{
1554-
ND_TCHECK2(*tptr, ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN);
1572+
if (stlv_len < ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN)
1573+
goto trunc;
15551574

15561575
ND_PRINT((ndo, "\n\t U:%d, M:%d, A:%d, RES:%d",
15571576
*(tptr) >> 7, (*(tptr) >> 6) & 0x01,
@@ -1569,14 +1588,15 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
15691588

15701589
tptr = tptr + 3;
15711590
len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
1591+
stlv_len = stlv_len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
15721592
tmp--;
15731593
}
15741594

15751595
break;
15761596

15771597
case ISIS_SUBTLV_SPBM_SI:
1578-
1579-
ND_TCHECK2(*tptr, 8);
1598+
if (stlv_len < 8)
1599+
goto trunc;
15801600

15811601
ND_PRINT((ndo, "\n\t BMAC: %08x", EXTRACT_32BITS(tptr)));
15821602
tptr = tptr+4;
@@ -1608,6 +1628,8 @@ isis_print_mt_capability_subtlv(netdissect_options *ndo,
16081628
default:
16091629
break;
16101630
}
1631+
tptr += stlv_len;
1632+
len -= stlv_len;
16111633
}
16121634
return 0;
16131635

Diff for: tests/TESTLIST

+4
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,10 @@ mobility_opt_asan mobility_opt_asan.pcap mobility_opt_asan.out -v
528528
mobility_opt_asan_2 mobility_opt_asan_2.pcap mobility_opt_asan_2.out -v
529529
mobility_opt_asan_3 mobility_opt_asan_3.pcap mobility_opt_asan_3.out -v
530530
mobility_opt_asan_4 mobility_opt_asan_4.pcap mobility_opt_asan_4.out -v
531+
isis_stlv_asan isis_stlv_asan.pcap isis_stlv_asan.out -v
532+
isis_stlv_asan-2 isis_stlv_asan-2.pcap isis_stlv_asan-2.out -v
533+
isis_stlv_asan-3 isis_stlv_asan-3.pcap isis_stlv_asan-3.out -v
534+
isis_stlv_asan-4 isis_stlv_asan-4.pcap isis_stlv_asan-4.out -v
531535

532536
# RTP tests
533537
# fuzzed pcap

Diff for: tests/isis-extd-ipreach-oobr.out

+1-16
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,7 @@
2424
AUX-MCID: ID: 69, Name: EIEEEIEEEIEEEIEEEIEEEIEEEIEEEIEE
2525
Lvl: 17737, Digest: 45 45 45 49 45 45 45 49 45 45 45 49 45 45 45 49 [|isis]
2626
unknown subTLV #69, length: 69
27-
unknown subTLV #69, length: 73
28-
unknown subTLV #69, length: 69
29-
unknown subTLV #69, length: 73
30-
unknown subTLV #69, length: 69
31-
unknown subTLV #69, length: 73
32-
unknown subTLV #69, length: 69
33-
unknown subTLV #69, length: 73
34-
unknown subTLV #69, length: 69
35-
unknown subTLV #69, length: 73
36-
unknown subTLV #69, length: 69
37-
unknown subTLV #69, length: 73
38-
unknown subTLV #69, length: 69
39-
unknown subTLV #69, length: 73
40-
unknown subTLV #69, length: 69
41-
unknown subTLV #69, length: 73
42-
unknown subTLV #69, length: 69
27+
[|isis]
4328
0x0000: 0000 0466 0049 4545 4549 4545 4549 4545
4429
0x0010: 4549 4545 4549 4545 4549 4545 4549 4545
4530
0x0020: 4549 4545 4549 4545 4549 4545 4549 4545

Diff for: tests/isis-seg-fault-2-v.out

+4-116
Original file line numberDiff line numberDiff line change
@@ -5,129 +5,17 @@ IS-IS, length 1497
55
Multi-Topology Capability TLV #144, length: 1
66
O: 1, RES: 4, MTID(s): 3073
77
unknown subTLV #4, length: 3
8-
unknown subTLV #73, length: 0
9-
unknown subTLV #10, length: 132
10-
unknown subTLV #4, length: 10
11-
unknown subTLV #0, length: 10
12-
unknown subTLV #0, length: 55
13-
SPBM Service Identifier and Unicast Address subTLV #3, length: 0
14-
BMAC: 00000606c201, RES: 2, VID: 2456
15-
unknown subTLV #204, length: 83
8+
unknown subTLV #132, length: 4
9+
unknown subTLV #55, length: 3
10+
unknown subTLV #6, length: 6
1611
unknown subTLV #8, length: 191
1712
unknown subTLV #0, length: 0
1813
unknown subTLV #0, length: 0
1914
unknown subTLV #0, length: 0
2015
unknown subTLV #0, length: 0
2116
unknown subTLV #0, length: 0
22-
unknown subTLV #0, length: 0
23-
unknown subTLV #0, length: 0
24-
unknown subTLV #82, length: 0
25-
unknown subTLV #0, length: 86
26-
unknown subTLV #0, length: 0
27-
unknown subTLV #0, length: 0
28-
unknown subTLV #0, length: 0
29-
unknown subTLV #37, length: 0
30-
unknown subTLV #0, length: 0
31-
unknown subTLV #0, length: 37
32-
unknown subTLV #0, length: 0
33-
unknown subTLV #0, length: 0
34-
unknown subTLV #0, length: 0
35-
unknown subTLV #0, length: 0
36-
unknown subTLV #0, length: 0
37-
unknown subTLV #0, length: 0
38-
unknown subTLV #0, length: 0
39-
unknown subTLV #0, length: 108
40-
unknown subTLV #0, length: 0
41-
unknown subTLV #0, length: 0
42-
unknown subTLV #0, length: 0
43-
unknown subTLV #0, length: 0
44-
unknown subTLV #0, length: 0
45-
unknown subTLV #0, length: 0
46-
unknown subTLV #0, length: 0
47-
unknown subTLV #37, length: 0
48-
unknown subTLV #48, length: 0
49-
unknown subTLV #0, length: 0
50-
unknown subTLV #0, length: 0
51-
unknown subTLV #0, length: 0
52-
unknown subTLV #0, length: 0
53-
unknown subTLV #37, length: 0
54-
unknown subTLV #0, length: 0
55-
unknown subTLV #0, length: 0
56-
unknown subTLV #172, length: 0
57-
unknown subTLV #0, length: 0
58-
unknown subTLV #0, length: 0
59-
unknown subTLV #0, length: 0
60-
unknown subTLV #0, length: 0
61-
unknown subTLV #0, length: 0
62-
unknown subTLV #0, length: 0
63-
unknown subTLV #0, length: 0
64-
unknown subTLV #0, length: 0
65-
unknown subTLV #0, length: 0
66-
unknown subTLV #0, length: 0
67-
unknown subTLV #76, length: 0
68-
unknown subTLV #0, length: 0
69-
unknown subTLV #0, length: 0
70-
unknown subTLV #0, length: 90
71-
unknown subTLV #0, length: 0
72-
unknown subTLV #0, length: 0
73-
unknown subTLV #0, length: 90
74-
unknown subTLV #0, length: 0
75-
unknown subTLV #0, length: 0
76-
unknown subTLV #37, length: 0
77-
unknown subTLV #0, length: 0
78-
unknown subTLV #0, length: 0
79-
unknown subTLV #0, length: 0
80-
unknown subTLV #0, length: 0
81-
unknown subTLV #0, length: 0
82-
unknown subTLV #0, length: 0
83-
unknown subTLV #0, length: 107
84-
unknown subTLV #0, length: 0
85-
unknown subTLV #0, length: 0
86-
unknown subTLV #0, length: 0
87-
unknown subTLV #0, length: 0
88-
unknown subTLV #0, length: 0
8917
unknown subTLV #0, length: 37
90-
unknown subTLV #0, length: 0
91-
unknown subTLV #0, length: 0
92-
unknown subTLV #0, length: 0
93-
unknown subTLV #0, length: 0
94-
unknown subTLV #2, length: 0
95-
unknown subTLV #0, length: 0
96-
unknown subTLV #37, length: 0
97-
unknown subTLV #0, length: 0
98-
unknown subTLV #0, length: 0
99-
unknown subTLV #0, length: 92
100-
unknown subTLV #0, length: 0
101-
unknown subTLV #113, length: 90
102-
unknown subTLV #0, length: 230
103-
unknown subTLV #0, length: 0
104-
unknown subTLV #79, length: 0
105-
unknown subTLV #0, length: 0
106-
unknown subTLV #0, length: 0
107-
unknown subTLV #234, length: 0
108-
unknown subTLV #0, length: 0
109-
unknown subTLV #64, length: 0
110-
unknown subTLV #0, length: 0
111-
unknown subTLV #0, length: 0
112-
unknown subTLV #0, length: 0
113-
unknown subTLV #0, length: 0
114-
unknown subTLV #0, length: 0
115-
unknown subTLV #0, length: 0
116-
unknown subTLV #0, length: 0
117-
unknown subTLV #0, length: 0
118-
unknown subTLV #37, length: 0
119-
unknown subTLV #0, length: 0
120-
unknown subTLV #0, length: 0
121-
unknown subTLV #0, length: 0
122-
unknown subTLV #37, length: 0
123-
unknown subTLV #0, length: 0
124-
unknown subTLV #0, length: 0
125-
unknown subTLV #0, length: 0
126-
unknown subTLV #0, length: 0
127-
unknown subTLV #0, length: 0
128-
unknown subTLV #2, length: 0
129-
unknown subTLV #0, length: 0
130-
unknown subTLV #0, length: 0
18+
[|isis]
13119
Area address(es) TLV #1, length: 4
13220
Area address (length: 3): 49.000a
13321
IPv4 Interface address(es) TLV #132, length: 4

Diff for: tests/isis_stlv_asan-2.out

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
UI 22! IS-IS, length 469869187
2+
L2 Lan IIH, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 224 (224)
3+
source-id: fed0.f90f.58af, holding time: 34047s, Flags: [unknown circuit type 0x00]
4+
lan-id: 0100.0088.a201.1c, Priority: 65, PDU length: 4096
5+
unknown TLV #0, length: 12
6+
0x0000: 0722 0583 1b01 0010 0505 0505
7+
Area address(es) TLV #1, length: 157
8+
IS Reachability TLV #2, length: 2
9+
bogus virtual flag 0x02
10+
IS Reachability TLV #2, length: 2
11+
bogus virtual flag 0x02
12+
IS Reachability TLV #2, length: 2
13+
bogus virtual flag 0x90
14+
Multi-Topology Capability TLV #144, length: 144
15+
O: 1, RES: 1, MTID(s): 144
16+
unknown subTLV #144, length: 2
17+
unknown subTLV #2, length: 0
18+
unknown subTLV #16, length: 1
19+
unknown subTLV #224, length: 0
20+
unknown subTLV #59, length: 0
21+
unknown subTLV #5, length: 166
22+
[|isis] [|isis]

Diff for: tests/isis_stlv_asan-2.pcap

323 Bytes
Binary file not shown.

Diff for: tests/isis_stlv_asan-3.out

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
UI 22! IS-IS, length 469869187
2+
L2 Lan IIH, hlen: 27, v: 1, pdu-v: 1, sys-id-len: 6 (0), max-area: 224 (224)
3+
source-id: fed0.f90f.58af, holding time: 34047s, Flags: [unknown circuit type 0x00]
4+
lan-id: 0100.0088.a201.1c, Priority: 65, PDU length: 4096
5+
unknown TLV #0, length: 12
6+
0x0000: 0722 0583 1b01 0010 019d e000
7+
unknown TLV #254, length: 0
8+
Prefix Neighbors TLV #5, length: 146
9+
Metric Block, Default Metric: 32, Internal
10+
Expense Metric: 0, Internal
11+
Error Metric: 0, Internal
12+
Address: 88.99ff.ffff.7fb5.0000/76
13+
Address: isonsap_string: illegal length/948
14+
Address: 95/8
15+
Address: 02/8
16+
Address: 02/8
17+
Address: 02/8
18+
Address: 90/8
19+
Multi-Topology Capability TLV #144, length: 144
20+
O: 1, RES: 1, MTID(s): 0
21+
unknown subTLV #107, length: 0
22+
unknown subTLV #0, length: 208
23+
[|isis] [|isis]

Diff for: tests/isis_stlv_asan-3.pcap

323 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)