From a09d2a7edc49fda20fb77960aed6346abbfdcdf3 Mon Sep 17 00:00:00 2001 From: Thomas Reim Date: Tue, 2 Oct 2018 09:43:03 +0200 Subject: [PATCH] Fix isakmp fragmentation bug in CVE-2016-10396 patch When applying NetBSD's CVE-2016-10396 patch Apple iPhones, which use a racoon client for IPSec based VPN access, cannot connect anymore to racoon VPN on the racoon server. Following server log entries outline the failure: Sep 14 06:42:28 vpnserver racoon[1775]: ERROR: Repeated fragment index mismatch Sep 14 06:42:28 vpnserver racoon[1775]: ERROR: Repeated last fragment index mismatch Sep 14 06:42:32 vpnserver racoon[1775]: ERROR: Repeated fragment index mismatch Sep 14 06:42:32 vpnserver racoon[1775]: ERROR: Repeated last fragment index mismatch Sep 14 06:42:35 vpnserver racoon[1775]: ERROR: Repeated fragment index mismatch Sep 14 06:42:35 vpnserver racoon[1775]: ERROR: Repeated last fragment index mismatch Sep 14 06:42:35 vpnserver racoon[1775]: ERROR: Repeated fragment index mismatch Sep 14 06:42:35 vpnserver racoon[1775]: ERROR: Repeated last fragment index mismatch Sep 14 06:42:39 vpnserver racoon[1775]: ERROR: phase1 negotiation failed due to time up. This update fixes a bug in the CVE-2016-10396 patch, which prevents racoon server from identifying a completely reassembled isakmp fragment chain. In addition, limited debugging has been added, as VPN clients may be blackballed due to the stricter fragment checks introduced by the CVE-2016-10396 patch. Signed-off-by: Thomas Reim --- debian/patches/CVE-2016-10396.patch | 46 +++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/debian/patches/CVE-2016-10396.patch b/debian/patches/CVE-2016-10396.patch index e123007..8907dc9 100644 --- a/debian/patches/CVE-2016-10396.patch +++ b/debian/patches/CVE-2016-10396.patch @@ -12,7 +12,7 @@ Index: pkg-ipsec-tools/src/racoon/isakmp_frag.c /* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */ -@@ -173,6 +173,43 @@ vendorid_frag_cap(gen) +@@ -173,6 +173,50 @@ vendorid_frag_cap(gen) return ntohl(hp[MD5_DIGEST_LENGTH / sizeof(*hp)]); } @@ -25,9 +25,16 @@ Index: pkg-ipsec-tools/src/racoon/isakmp_frag.c + /* no frag yet, just insert at beginning of list */ + if (iph1->frag_chain == NULL) { + iph1->frag_chain = item; ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "first fragment inserted (#%d)\n", ++ item->frag_num); + return 0; + } + ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "inserting fragment #%d\n", ++ item->frag_num); ++ + do { + /* duplicate fragment number, abort (CVE-2016-10396) */ + if (citem->frag_num == item->frag_num) @@ -56,7 +63,19 @@ Index: pkg-ipsec-tools/src/racoon/isakmp_frag.c int isakmp_frag_extract(iph1, msg) struct ph1handle *iph1; -@@ -224,39 +261,43 @@ isakmp_frag_extract(iph1, msg) +@@ -187,6 +231,11 @@ isakmp_frag_extract(iph1, msg) + char *data; + int i; + ++ if (iph1->frag_chain == NULL) { ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "fragmented IKE phase 1 payload:\n"); ++ } ++ + if (msg->l < sizeof(*isakmp) + sizeof(*frag)) { + plog(LLV_ERROR, LOCATION, NULL, "Message too short\n"); + return -1; +@@ -224,40 +273,51 @@ isakmp_frag_extract(iph1, msg) item->frag_next = NULL; item->frag_packet = buf; @@ -111,19 +130,28 @@ Index: pkg-ipsec-tools/src/racoon/isakmp_frag.c - item = item->frag_next; - } while (item != NULL); - -+ if (item->frag_num != i) -+ break; -+ item = item->frag_next; - if (item == NULL) /* Not found */ +- if (item == NULL) /* Not found */ ++ if (item == NULL || ++ item->frag_num != i) { ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "fragment #%d still missing\n", ++ i); break; ++ } ++ item = item->frag_next; } - if (item != NULL) /* It is complete */ -+ if (i > last_frag) /* It is complete */ ++ if (i > last_frag) {/* It is complete */ ++ plog(LLV_DEBUG, LOCATION, NULL, ++ "Fragment #%d completed payload.\n", ++ frag->index); return 1; ++ } } -@@ -291,15 +332,9 @@ isakmp_frag_reassembly(iph1) + return 0; +@@ -291,15 +351,9 @@ isakmp_frag_reassembly(iph1) } data = buf->v; @@ -141,7 +169,7 @@ Index: pkg-ipsec-tools/src/racoon/isakmp_frag.c plog(LLV_ERROR, LOCATION, NULL, "Missing fragment #%d\n", i); vfree(buf); -@@ -308,6 +343,7 @@ isakmp_frag_reassembly(iph1) +@@ -308,6 +362,7 @@ isakmp_frag_reassembly(iph1) } memcpy(data, item->frag_packet->v, item->frag_packet->l); data += item->frag_packet->l; -- 2.17.1