Control: tags -1 + pending patch On Mon, Jul 10, 2017 at 11:18:35PM +0200, Moritz Muehlenhoff wrote: > > Please see http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10396 >
I believe that the attached debdiff, derived from NetBSD's fix, should address this problem. It should apply with only metadata modifications as far back as oldstable. I'll upload to unstable as soon as I've satisfied myself that the update doesn't introduce any regressions. I don't believe there's a PoC for the attack, so I don't know that we'll be able to confirm definitively that the issue is resolved. If anybody has PoC code or is interested in putting some together, I'd be interested in testing the fix more thoroughly... Uploads targeting (old)stable will follow shortly after unstable, assuming no issues. noah
diff -Nru ipsec-tools-0.8.2+20140711/debian/changelog ipsec-tools-0.8.2+20140711/debian/changelog --- ipsec-tools-0.8.2+20140711/debian/changelog 2016-12-01 09:49:16.000000000 +0000 +++ ipsec-tools-0.8.2+20140711/debian/changelog 2017-07-18 17:22:32.000000000 +0000 @@ -1,3 +1,9 @@ +ipsec-tools (1:0.8.2+20140711-9) UNRELEASED; urgency=medium + + * Import NetBSD's patch to address CVE-2016-10396 (Closes: #867986) + + -- Noah Meyerhans <no...@debian.org> Tue, 18 Jul 2017 17:22:32 +0000 + ipsec-tools (1:0.8.2+20140711-8) unstable; urgency=medium * Depend on libfl-dev to follow flex changes (Closes: #846430) diff -Nru ipsec-tools-0.8.2+20140711/debian/patches/CVE-2016-10396.patch ipsec-tools-0.8.2+20140711/debian/patches/CVE-2016-10396.patch --- ipsec-tools-0.8.2+20140711/debian/patches/CVE-2016-10396.patch 1970-01-01 00:00:00.000000000 +0000 +++ ipsec-tools-0.8.2+20140711/debian/patches/CVE-2016-10396.patch 2017-07-18 17:22:32.000000000 +0000 @@ -0,0 +1,194 @@ +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 + +--- 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,38 @@ 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; ++ ++ if (iph1->frag_chain == NULL) { ++ iph1->frag_chain = item; ++ return 0; ++ } ++ ++ do { ++ if (citem->frag_num == item->frag_num) ++ return -1; ++ ++ if (citem->frag_num > item->frag_num) { ++ if (pitem) ++ pitem->frag_next = item; ++ item->frag_next = citem; ++ break; ++ } ++ ++ pitem = citem; ++ citem = citem->frag_next; ++ } while (citem != NULL); ++ ++ /* we reached the end of the list, insert */ ++ if (citem == NULL) ++ pitem->frag_next = item; ++ return 0; ++} ++ + int + isakmp_frag_extract(iph1, msg) + struct ph1handle *iph1; +@@ -224,39 +256,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 +327,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 +338,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 + diff -Nru ipsec-tools-0.8.2+20140711/debian/patches/series ipsec-tools-0.8.2+20140711/debian/patches/series --- ipsec-tools-0.8.2+20140711/debian/patches/series 2016-12-01 09:49:16.000000000 +0000 +++ ipsec-tools-0.8.2+20140711/debian/patches/series 2017-07-18 17:22:32.000000000 +0000 @@ -15,3 +15,4 @@ bug785778-null-pointer-deref.patch bug777918-implicit-int.patch bug790244-glibc-bsd-source-obsolete.patch +CVE-2016-10396.patch