forked from gentoo/gentoo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net-vpn/ipsec-tools: add patch for CVE-2016-1039, bug #624832
Package-Manager: Portage-2.3.99, Repoman-2.3.22 Signed-off-by: Anthony G. Basile <[email protected]>
- Loading branch information
Showing
2 changed files
with
484 additions
and
0 deletions.
There are no files selected for viewing
201 changes: 201 additions & 0 deletions
201
net-vpn/ipsec-tools/files/ipsec-tools-CVE-2016-10396.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
Description: Fix remotely exploitable DoS. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10396 | ||
Source: vendor; https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=51682 | ||
Bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=867986 | ||
|
||
Index: pkg-ipsec-tools/src/racoon/isakmp_frag.c | ||
=================================================================== | ||
--- pkg-ipsec-tools.orig/src/racoon/isakmp_frag.c | ||
+++ pkg-ipsec-tools/src/racoon/isakmp_frag.c | ||
@@ -1,4 +1,4 @@ | ||
-/* $NetBSD: isakmp_frag.c,v 1.5 2009/04/22 11:24:20 tteras Exp $ */ | ||
+/* $NetBSD: isakmp_frag.c,v 1.5.36.1 2017/04/21 16:50:42 bouyer Exp $ */ | ||
|
||
/* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */ | ||
|
||
@@ -173,6 +173,43 @@ vendorid_frag_cap(gen) | ||
return ntohl(hp[MD5_DIGEST_LENGTH / sizeof(*hp)]); | ||
} | ||
|
||
+static int | ||
+isakmp_frag_insert(struct ph1handle *iph1, struct isakmp_frag_item *item) | ||
+{ | ||
+ struct isakmp_frag_item *pitem = NULL; | ||
+ struct isakmp_frag_item *citem = iph1->frag_chain; | ||
+ | ||
+ /* no frag yet, just insert at beginning of list */ | ||
+ if (iph1->frag_chain == NULL) { | ||
+ iph1->frag_chain = item; | ||
+ return 0; | ||
+ } | ||
+ | ||
+ do { | ||
+ /* duplicate fragment number, abort (CVE-2016-10396) */ | ||
+ if (citem->frag_num == item->frag_num) | ||
+ return -1; | ||
+ | ||
+ /* need to insert before current item */ | ||
+ if (citem->frag_num > item->frag_num) { | ||
+ if (pitem != NULL) | ||
+ pitem->frag_next = item; | ||
+ else | ||
+ /* insert at the beginning of the list */ | ||
+ iph1->frag_chain = item; | ||
+ item->frag_next = citem; | ||
+ return 0; | ||
+ } | ||
+ | ||
+ pitem = citem; | ||
+ citem = citem->frag_next; | ||
+ } while (citem != NULL); | ||
+ | ||
+ /* we reached the end of the list, insert */ | ||
+ pitem->frag_next = item; | ||
+ return 0; | ||
+} | ||
+ | ||
int | ||
isakmp_frag_extract(iph1, msg) | ||
struct ph1handle *iph1; | ||
@@ -224,39 +261,43 @@ isakmp_frag_extract(iph1, msg) | ||
item->frag_next = NULL; | ||
item->frag_packet = buf; | ||
|
||
- /* Look for the last frag while inserting the new item in the chain */ | ||
- if (item->frag_last) | ||
- last_frag = item->frag_num; | ||
+ /* Check for the last frag before inserting the new item in the chain */ | ||
+ if (item->frag_last) { | ||
+ /* if we have the last fragment, indices must match */ | ||
+ if (iph1->frag_last_index != 0 && | ||
+ item->frag_last != iph1->frag_last_index) { | ||
+ plog(LLV_ERROR, LOCATION, NULL, | ||
+ "Repeated last fragment index mismatch\n"); | ||
+ racoon_free(item); | ||
+ vfree(buf); | ||
+ return -1; | ||
+ } | ||
|
||
- if (iph1->frag_chain == NULL) { | ||
- iph1->frag_chain = item; | ||
- } else { | ||
- struct isakmp_frag_item *current; | ||
+ last_frag = iph1->frag_last_index = item->frag_num; | ||
+ } | ||
|
||
- current = iph1->frag_chain; | ||
- while (current->frag_next) { | ||
- if (current->frag_last) | ||
- last_frag = item->frag_num; | ||
- current = current->frag_next; | ||
- } | ||
- current->frag_next = item; | ||
+ /* insert fragment into chain */ | ||
+ if (isakmp_frag_insert(iph1, item) == -1) { | ||
+ plog(LLV_ERROR, LOCATION, NULL, | ||
+ "Repeated fragment index mismatch\n"); | ||
+ racoon_free(item); | ||
+ vfree(buf); | ||
+ return -1; | ||
} | ||
|
||
- /* If we saw the last frag, check if the chain is complete */ | ||
+ /* If we saw the last frag, check if the chain is complete | ||
+ * we have a sorted list now, so just walk through */ | ||
if (last_frag != 0) { | ||
+ item = iph1->frag_chain; | ||
for (i = 1; i <= last_frag; i++) { | ||
- item = iph1->frag_chain; | ||
- do { | ||
- if (item->frag_num == i) | ||
- break; | ||
- item = item->frag_next; | ||
- } while (item != NULL); | ||
- | ||
+ if (item->frag_num != i) | ||
+ break; | ||
+ item = item->frag_next; | ||
if (item == NULL) /* Not found */ | ||
break; | ||
} | ||
|
||
- if (item != NULL) /* It is complete */ | ||
+ if (i > last_frag) /* It is complete */ | ||
return 1; | ||
} | ||
|
||
@@ -291,15 +332,9 @@ isakmp_frag_reassembly(iph1) | ||
} | ||
data = buf->v; | ||
|
||
+ item = iph1->frag_chain; | ||
for (i = 1; i <= frag_count; i++) { | ||
- item = iph1->frag_chain; | ||
- do { | ||
- if (item->frag_num == i) | ||
- break; | ||
- item = item->frag_next; | ||
- } while (item != NULL); | ||
- | ||
- if (item == NULL) { | ||
+ if (item->frag_num != i) { | ||
plog(LLV_ERROR, LOCATION, NULL, | ||
"Missing fragment #%d\n", i); | ||
vfree(buf); | ||
@@ -308,6 +343,7 @@ isakmp_frag_reassembly(iph1) | ||
} | ||
memcpy(data, item->frag_packet->v, item->frag_packet->l); | ||
data += item->frag_packet->l; | ||
+ item = item->frag_next; | ||
} | ||
|
||
out: | ||
Index: pkg-ipsec-tools/src/racoon/isakmp_inf.c | ||
=================================================================== | ||
--- pkg-ipsec-tools.orig/src/racoon/isakmp_inf.c | ||
+++ pkg-ipsec-tools/src/racoon/isakmp_inf.c | ||
@@ -720,6 +720,7 @@ isakmp_info_send_nx(isakmp, remote, loca | ||
#endif | ||
#ifdef ENABLE_FRAG | ||
iph1->frag = 0; | ||
+ iph1->frag_last_index = 0; | ||
iph1->frag_chain = NULL; | ||
#endif | ||
|
||
Index: pkg-ipsec-tools/src/racoon/isakmp.c | ||
=================================================================== | ||
--- pkg-ipsec-tools.orig/src/racoon/isakmp.c | ||
+++ pkg-ipsec-tools/src/racoon/isakmp.c | ||
@@ -1072,6 +1072,7 @@ isakmp_ph1begin_i(rmconf, remote, local) | ||
iph1->frag = 1; | ||
else | ||
iph1->frag = 0; | ||
+ iph1->frag_last_index = 0; | ||
iph1->frag_chain = NULL; | ||
#endif | ||
iph1->approval = NULL; | ||
@@ -1176,6 +1177,7 @@ isakmp_ph1begin_r(msg, remote, local, et | ||
#endif | ||
#ifdef ENABLE_FRAG | ||
iph1->frag = 0; | ||
+ iph1->frag_last_index = 0; | ||
iph1->frag_chain = NULL; | ||
#endif | ||
iph1->approval = NULL; | ||
Index: pkg-ipsec-tools/src/racoon/handler.h | ||
=================================================================== | ||
--- pkg-ipsec-tools.orig/src/racoon/handler.h | ||
+++ pkg-ipsec-tools/src/racoon/handler.h | ||
@@ -1,4 +1,4 @@ | ||
-/* $NetBSD: handler.h,v 1.25 2010/11/17 10:40:41 tteras Exp $ */ | ||
+/* $NetBSD: handler.h,v 1.26 2017/01/24 19:23:56 christos Exp $ */ | ||
|
||
/* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */ | ||
|
||
@@ -141,6 +141,7 @@ struct ph1handle { | ||
#endif | ||
#ifdef ENABLE_FRAG | ||
int frag; /* IKE phase 1 fragmentation */ | ||
+ int frag_last_index; | ||
struct isakmp_frag_item *frag_chain; /* Received fragments */ | ||
#endif | ||
|
Oops, something went wrong.