Skip to content

Commit de981e6

Browse files
guyharrisinfrastation
authored andcommitted
CVE-2017-12901/EIGRP: Do more length checks.
This fixes a buffer over-read discovered by Forcepoint's security researchers Otto Airamo & Antti Levomäki. Add a test using the capture file supplied by the reporter(s).
1 parent 7ac73d6 commit de981e6

File tree

4 files changed

+4184
-0
lines changed

4 files changed

+4184
-0
lines changed

Diff for: print-eigrp.c

+47
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
/*
3232
* packet format documented at
3333
* http://www.rhyshaden.com/eigrp.htm
34+
* RFC 7868
3435
*/
3536

3637
struct eigrp_common_header {
@@ -246,6 +247,12 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
246247

247248
/* ok they seem to want to know everything - lets fully decode it */
248249

250+
if (len < sizeof(struct eigrp_common_header)) {
251+
ND_PRINT((ndo, "EIGRP %s, length: %u (too short, < %u)",
252+
tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
253+
len, (u_int) sizeof(struct eigrp_common_header)));
254+
return;
255+
}
249256
tlen=len-sizeof(struct eigrp_common_header);
250257

251258
/* FIXME print other header info */
@@ -286,6 +293,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
286293
eigrp_tlv_type,
287294
eigrp_tlv_len));
288295

296+
if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) {
297+
ND_PRINT((ndo, " (too short, < %u)",
298+
(u_int) sizeof(struct eigrp_tlv_header)));
299+
break;
300+
}
289301
tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
290302
tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
291303

@@ -296,6 +308,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
296308

297309
case EIGRP_TLV_GENERAL_PARM:
298310
tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
311+
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) {
312+
ND_PRINT((ndo, " (too short, < %u)",
313+
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm))));
314+
break;
315+
}
299316

300317
ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
301318
EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
@@ -308,6 +325,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
308325

309326
case EIGRP_TLV_SW_VERSION:
310327
tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
328+
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) {
329+
ND_PRINT((ndo, " (too short, < %u)",
330+
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version))));
331+
break;
332+
}
311333

312334
ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u",
313335
tlv_ptr.eigrp_tlv_sw_version->ios_major,
@@ -318,6 +340,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
318340

319341
case EIGRP_TLV_IP_INT:
320342
tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
343+
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) {
344+
ND_PRINT((ndo, " (too short, < %u)",
345+
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int))));
346+
break;
347+
}
321348

322349
bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
323350
if (bit_length > 32) {
@@ -347,6 +374,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
347374

348375
case EIGRP_TLV_IP_EXT:
349376
tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
377+
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) {
378+
ND_PRINT((ndo, " (too short, < %u)",
379+
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext))));
380+
break;
381+
}
350382

351383
bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
352384
if (bit_length > 32) {
@@ -384,6 +416,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
384416

385417
case EIGRP_TLV_AT_CABLE_SETUP:
386418
tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
419+
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) {
420+
ND_PRINT((ndo, " (too short, < %u)",
421+
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup))));
422+
break;
423+
}
387424

388425
ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u",
389426
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
@@ -393,6 +430,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
393430

394431
case EIGRP_TLV_AT_INT:
395432
tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
433+
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) {
434+
ND_PRINT((ndo, " (too short, < %u)",
435+
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int))));
436+
break;
437+
}
396438

397439
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
398440
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
@@ -416,6 +458,11 @@ eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int
416458

417459
case EIGRP_TLV_AT_EXT:
418460
tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
461+
if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) {
462+
ND_PRINT((ndo, " (too short, < %u)",
463+
(u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext))));
464+
break;
465+
}
419466

420467
ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
421468
EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),

Diff for: tests/TESTLIST

+1
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ icmp-cksum-oobr-3 icmp-cksum-oobr-3.pcap icmp-cksum-oobr-3.out -vvv -e
461461
icmp-cksum-oobr-4 icmp-cksum-oobr-4.pcap icmp-cksum-oobr-4.out -vvv -e
462462
tok2str-oobr-1 tok2str-oobr-1.pcap tok2str-oobr-1.out -vvv -e
463463
tok2str-oobr-2 tok2str-oobr-2.pcap tok2str-oobr-2.out -vvv -e
464+
eigrp-tlv-oobr eigrp-tlv-oobr.pcap eigrp-tlv-oobr.out -vvv -e
464465

465466
# RTP tests
466467
# fuzzed pcap

0 commit comments

Comments
 (0)