|
|
- 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: ipsec-tools-0.8.2/src/racoon/isakmp_frag.c
- ===================================================================
- --- ipsec-tools-0.8.2.orig/src/racoon/isakmp_frag.c
- +++ ipsec-tools-0.8.2/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: ipsec-tools-0.8.2/src/racoon/isakmp_inf.c
- ===================================================================
- --- ipsec-tools-0.8.2.orig/src/racoon/isakmp_inf.c
- +++ ipsec-tools-0.8.2/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: ipsec-tools-0.8.2/src/racoon/isakmp.c
- ===================================================================
- --- ipsec-tools-0.8.2.orig/src/racoon/isakmp.c
- +++ ipsec-tools-0.8.2/src/racoon/isakmp.c
- @@ -1071,6 +1071,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;
- @@ -1175,6 +1176,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: ipsec-tools-0.8.2/src/racoon/handler.h
- ===================================================================
- --- ipsec-tools-0.8.2.orig/src/racoon/handler.h
- +++ ipsec-tools-0.8.2/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
-
|