summary refs log tree commit diff
diff options
context:
space:
mode:
authorLinus Heckemann <git@sphalerite.org>2019-10-04 12:33:31 +0200
committerLinus Heckemann <git@sphalerite.org>2019-10-04 12:33:31 +0200
commit3682a3b0b1c99c61735cab2619cbf2dcc06cde99 (patch)
treed299b23ab082b15709f6d2188909650fce2901a0
parentc6be8bfc1011c82ea4cfa99ec87acc1c1b27922b (diff)
downloadnixpkgs-3682a3b0b1c99c61735cab2619cbf2dcc06cde99.tar
nixpkgs-3682a3b0b1c99c61735cab2619cbf2dcc06cde99.tar.gz
nixpkgs-3682a3b0b1c99c61735cab2619cbf2dcc06cde99.tar.bz2
nixpkgs-3682a3b0b1c99c61735cab2619cbf2dcc06cde99.tar.lz
nixpkgs-3682a3b0b1c99c61735cab2619cbf2dcc06cde99.tar.xz
nixpkgs-3682a3b0b1c99c61735cab2619cbf2dcc06cde99.tar.zst
nixpkgs-3682a3b0b1c99c61735cab2619cbf2dcc06cde99.zip
ipsecTools: ship patch directly
No longer available since anonscm.debian.org is shut
down (#39927). Replacement obtained from OpenSUSE source package
http://download.opensuse.org/repositories/openSUSE:/Factory/standard/src/ipsec-tools-0.8.2-9.6.src.rpm
-rw-r--r--pkgs/os-specific/linux/ipsec-tools/CVE-2016-10396.patch193
-rw-r--r--pkgs/os-specific/linux/ipsec-tools/default.nix5
2 files changed, 194 insertions, 4 deletions
diff --git a/pkgs/os-specific/linux/ipsec-tools/CVE-2016-10396.patch b/pkgs/os-specific/linux/ipsec-tools/CVE-2016-10396.patch
new file mode 100644
index 00000000000..b644d46f8c9
--- /dev/null
+++ b/pkgs/os-specific/linux/ipsec-tools/CVE-2016-10396.patch
@@ -0,0 +1,193 @@
+From: Antoine_Beaupre <anarcat@orangeseeds.org>
+Acked-by: Jiri Bohac <jbohac@suse.cz>
+Subject: PR/51682: Avoid DoS with fragment out of order insertion; keep fragments sorted in the list.
+References: bsc#1047443, CVE-2016-10396
+
+
+
+Index: a/src/racoon/handler.h
+===================================================================
+--- a/src/racoon/handler.h.orig	2018-01-26 18:05:21.114764376 +0100
++++ a/src/racoon/handler.h	2018-01-26 18:05:33.986741103 +0100
+@@ -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
+ 
+Index: a/src/racoon/isakmp.c
+===================================================================
+--- a/src/racoon/isakmp.c.orig	2018-01-26 18:05:21.118764369 +0100
++++ a/src/racoon/isakmp.c	2018-01-26 18:05:33.986741103 +0100
+@@ -1069,6 +1069,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;
+@@ -1173,6 +1174,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: a/src/racoon/isakmp_frag.c
+===================================================================
+--- a/src/racoon/isakmp_frag.c.orig	2018-01-26 18:05:21.118764369 +0100
++++ a/src/racoon/isakmp_frag.c	2018-01-26 18:05:33.986741103 +0100
+@@ -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:
+
+
+diff -u -p -r1.50 -r1.51
+--- a/src/racoon/isakmp_inf.c	2013/04/12 09:53:10	1.50
++++ a/src/racoon/isakmp_inf.c	2017/01/24 19:23:56	1.51
+@@ -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
+ 
diff --git a/pkgs/os-specific/linux/ipsec-tools/default.nix b/pkgs/os-specific/linux/ipsec-tools/default.nix
index 0aa074b4df8..551fc61f814 100644
--- a/pkgs/os-specific/linux/ipsec-tools/default.nix
+++ b/pkgs/os-specific/linux/ipsec-tools/default.nix
@@ -19,10 +19,7 @@ stdenv.mkDerivation rec {
   patches = [
     ./dont-create-localstatedir-during-install.patch
     ./CVE-2015-4047.patch
-    (fetchpatch {
-      url = "https://anonscm.debian.org/cgit/pkg-ipsec-tools/pkg-ipsec-tools.git/plain/debian/patches/CVE-2016-10396.patch?id=62ac12648a4eb7c5ba5dba0f81998d1acf310d8b";
-      sha256 = "1kf7j2pf1blni52z7q41n0yisqb7gvk01lvldr319zaxxg7rm84a";
-    })
+    ./CVE-2016-10396.patch
   ];
 
   # fix build with newer gcc versions