Skip to content

Commit 2c2cfbd

Browse files
guyharrisinfrastation
authored andcommitted
CVE-2017-13037/IP: Add bounds checks when printing time stamp options.
This fixes a buffer over-read discovered by Bhargava Shastry, SecT/TU Berlin. Add a test using the capture file supplied by the reporter(s), modified so the capture file won't be rejected as an invalid capture.
1 parent c2f3b23 commit 2c2cfbd

File tree

4 files changed

+14
-3
lines changed

4 files changed

+14
-3
lines changed

Diff for: print-ip.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ nextproto4_cksum(netdissect_options *ndo,
168168
return (in_cksum(vec, 2));
169169
}
170170

171-
static void
171+
static int
172172
ip_printts(netdissect_options *ndo,
173173
register const u_char *cp, u_int length)
174174
{
@@ -179,16 +179,18 @@ ip_printts(netdissect_options *ndo,
179179

180180
if (length < 4) {
181181
ND_PRINT((ndo, "[bad length %u]", length));
182-
return;
182+
return (0);
183183
}
184184
ND_PRINT((ndo, " TS{"));
185185
hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
186186
if ((length - 4) & (hoplen-1))
187187
ND_PRINT((ndo, "[bad length %u]", length));
188+
ND_TCHECK(cp[2]);
188189
ptr = cp[2] - 1;
189190
len = 0;
190191
if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
191192
ND_PRINT((ndo, "[bad ptr %u]", cp[2]));
193+
ND_TCHECK(cp[3]);
192194
switch (cp[3]&0xF) {
193195
case IPOPT_TS_TSONLY:
194196
ND_PRINT((ndo, "TSONLY"));
@@ -217,6 +219,7 @@ ip_printts(netdissect_options *ndo,
217219
for (len = 4; len < length; len += hoplen) {
218220
if (ptr == len)
219221
type = " ^ ";
222+
ND_TCHECK2(cp[len], hoplen);
220223
ND_PRINT((ndo, "%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
221224
hoplen!=8 ? "" : ipaddr_string(ndo, &cp[len])));
222225
type = " ";
@@ -229,6 +232,10 @@ ip_printts(netdissect_options *ndo,
229232
ND_PRINT((ndo, " [%d hops not recorded]} ", cp[3]>>4));
230233
else
231234
ND_PRINT((ndo, "}"));
235+
return (0);
236+
237+
trunc:
238+
return (-1);
232239
}
233240

234241
/*
@@ -278,7 +285,8 @@ ip_optprint(netdissect_options *ndo,
278285
return;
279286

280287
case IPOPT_TS:
281-
ip_printts(ndo, cp, option_len);
288+
if (ip_printts(ndo, cp, option_len) == -1)
289+
goto trunc;
282290
break;
283291

284292
case IPOPT_RR: /* fall through */

Diff for: tests/TESTLIST

+1
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ pim_header_asan-4 pim_header_asan-4.pcap pim_header_asan-4.out -v
552552
ip6_frag_asan ip6_frag_asan.pcap ip6_frag_asan.out -v
553553
radius_attr_asan radius_attr_asan.pcap radius_attr_asan.out -v
554554
ospf6_decode_v3_asan ospf6_decode_v3_asan.pcap ospf6_decode_v3_asan.out -v
555+
ip_ts_opts_asan ip_ts_opts_asan.pcap ip_ts_opts_asan.out -v
555556

556557
# RTP tests
557558
# fuzzed pcap

Diff for: tests/ip_ts_opts_asan.out

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
IP (tos 0xe2,ECT(0), id 32, offset 0, flags [+, DF, rsvd], proto ICMP (1), length 65319, options (timestamp TS{[bad length 14]TS+ADDR ^ 1229070338@0.0.52.112[|ip]), bad cksum a09b (->90a7)!)
2+
149.8.33.81 > 95.18.83.227: [|icmp]

Diff for: tests/ip_ts_opts_asan.pcap

90 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)