Skip to content

Commit 8dca25d

Browse files
guyharrisinfrastation
authored andcommitted
CVE-2017-13690/IKEv2: Fix some bounds checks.
Use a pointer of the correct type in ND_TCHECK(), or use ND_TCHECK2() and provide the correct length. While we're at it, remove the blank line between some checks and the UNALIGNED_MEMCPY()s they protect. Also, note the places where we print the entire payload. 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).
1 parent 061e737 commit 8dca25d

File tree

4 files changed

+20
-7
lines changed

4 files changed

+20
-7
lines changed

Diff for: print-isakmp.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,7 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
13131313
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
13141314
ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
13151315
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1316+
/* Print the entire payload in hex */
13161317
ND_PRINT((ndo," "));
13171318
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
13181319
goto trunc;
@@ -1515,6 +1516,7 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
15151516
ND_PRINT((ndo," len=%d", item_len - 4));
15161517
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
15171518
if (2 < ndo->ndo_vflag && 4 < item_len) {
1519+
/* Print the entire payload in hex */
15181520
ND_PRINT((ndo," "));
15191521
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
15201522
goto trunc;
@@ -1547,6 +1549,7 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
15471549
ND_PRINT((ndo," len=%d", item_len - 4));
15481550
ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
15491551
if (2 < ndo->ndo_vflag && 4 < item_len) {
1552+
/* Print the entire payload in hex */
15501553
ND_PRINT((ndo," "));
15511554
if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
15521555
goto trunc;
@@ -1571,6 +1574,7 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
15711574
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
15721575
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
15731576
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1577+
/* Print the entire payload in hex */
15741578
ND_PRINT((ndo," "));
15751579
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
15761580
goto trunc;
@@ -1595,6 +1599,7 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
15951599
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
15961600
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
15971601
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1602+
/* Print the entire payload in hex */
15981603
ND_PRINT((ndo," "));
15991604
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
16001605
goto trunc;
@@ -1850,6 +1855,7 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
18501855
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
18511856
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
18521857
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1858+
/* Print the entire payload in hex */
18531859
ND_PRINT((ndo," "));
18541860
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
18551861
goto trunc;
@@ -1884,6 +1890,7 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay,
18841890

18851891
ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
18861892
if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1893+
/* Print the entire payload in hex */
18871894
ND_PRINT((ndo," "));
18881895
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
18891896
goto trunc;
@@ -2022,7 +2029,6 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
20222029
if (prop_length < sizeof(*ext))
20232030
goto toolong;
20242031
ND_TCHECK(*ext);
2025-
20262032
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
20272033

20282034
/*
@@ -2109,7 +2115,6 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
21092115
if (sa_length < sizeof(*ext))
21102116
goto toolong;
21112117
ND_TCHECK(*ext);
2112-
21132118
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
21142119

21152120
/*
@@ -2170,7 +2175,7 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay,
21702175
const struct ikev2_ke *k;
21712176

21722177
k = (const struct ikev2_ke *)ext;
2173-
ND_TCHECK(*ext);
2178+
ND_TCHECK(*k);
21742179
UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
21752180
ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
21762181

@@ -2195,19 +2200,22 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
21952200
uint32_t phase _U_, uint32_t doi _U_,
21962201
uint32_t proto _U_, int depth _U_)
21972202
{
2203+
const struct ikev2_id *idp;
21982204
struct ikev2_id id;
21992205
int id_len, idtype_len, i;
22002206
unsigned int dumpascii, dumphex;
22012207
const unsigned char *typedata;
22022208

2203-
ND_TCHECK(*ext);
2209+
idp = (const struct ikev2_id *)ext;
2210+
ND_TCHECK(*idp);
22042211
UNALIGNED_MEMCPY(&id, ext, sizeof(id));
22052212
ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
22062213

22072214
id_len = ntohs(id.h.len);
22082215

22092216
ND_PRINT((ndo," len=%d", id_len - 4));
22102217
if (2 < ndo->ndo_vflag && 4 < id_len) {
2218+
/* Print the entire payload in hex */
22112219
ND_PRINT((ndo," "));
22122220
if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4))
22132221
goto trunc;
@@ -2303,7 +2311,7 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay,
23032311
const u_char *authdata = (const u_char*)ext + sizeof(a);
23042312
unsigned int len;
23052313

2306-
ND_TCHECK(*ext);
2314+
ND_TCHECK2(*ext, sizeof(a));
23072315
UNALIGNED_MEMCPY(&a, ext, sizeof(a));
23082316
ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
23092317
len = ntohs(a.h.len);
@@ -2599,6 +2607,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay,
25992607
else ND_PRINT((ndo, "."));
26002608
}
26012609
if (2 < ndo->ndo_vflag && 4 < len) {
2610+
/* Print the entire payload in hex */
26022611
ND_PRINT((ndo," "));
26032612
if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
26042613
goto trunc;
@@ -2764,7 +2773,6 @@ ikev1_sub_print(netdissect_options *ndo,
27642773

27652774
while (np) {
27662775
ND_TCHECK(*ext);
2767-
27682776
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
27692777

27702778
ND_TCHECK2(*ext, ntohs(e.len));
@@ -2932,7 +2940,6 @@ ikev2_sub_print(netdissect_options *ndo,
29322940
cp = (const u_char *)ext;
29332941
while (np) {
29342942
ND_TCHECK(*ext);
2935-
29362943
UNALIGNED_MEMCPY(&e, ext, sizeof(e));
29372944

29382945
ND_TCHECK2(*ext, ntohs(e.len));

Diff for: tests/TESTLIST

+1
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ isis-extd-isreach-oobr isis-extd-isreach-oobr.pcap isis-extd-isreach-oobr.out -v
578578
olsr-oobr-1 olsr-oobr-1.pcap olsr-oobr-1.out -v
579579
olsr-oobr-2 olsr-oobr-2.pcap olsr-oobr-2.out -v
580580
ikev1_id_ipv6_addr_subnet-oobr ikev1_id_ipv6_addr_subnet-oobr.pcap ikev1_id_ipv6_addr_subnet-oobr.out -v
581+
isakmp-various-oobr isakmp-various-oobr.pcap isakmp-various-oobr.out -v
581582

582583
# bad packets from Katie Holly
583584
mlppp-oobr mlppp-oobr.pcap mlppp-oobr.out

Diff for: tests/isakmp-various-oobr.out

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
IP (tos 0xfb,CE, ttl 17, id 21263, offset 0, flags [+, DF, rsvd], proto UDP (17), length 296, bad cksum 1ff (->f67d)!)
2+
16.0.128.20.500 > 12.251.225.45.49152: isakmp 1.0 msgid 10101010: phase 2/others ? #16[]:
3+
( [|v2ke]) (len mismatch: isakmp 2130706432/ip 268)
4+
IP (tos 0x12,ECT(0), ttl 17, id 21263, offset 4096, flags [DF, rsvd], proto UDP (17), length 296, bad cksum 1ff (->939f)!)
5+
0.0.0.5 > 0.0.0.0: ip-proto-17

Diff for: tests/isakmp-various-oobr.pcap

206 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)