blob: 19220c4e756696f40c82189bd8fe9b1fdc9ddba9 [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001Upstream-Status: Backport [https://anonscm.debian.org/cgit/pkg-ipsec-tools/pkg-ipsec-tools.git/plain/debian/patches/CVE-2016-10396.patch?id=62ac12648a4eb7c5ba5dba0f81998d1acf310d8b]
2
Brad Bishop34ae6002019-04-08 15:21:03 -04003CVE: CVE-2016-10396.
Brad Bishopd7bf8c12018-02-25 22:55:05 -05004
5Signed-off-by: Kai Kang <kai.kang@windriver.com>
6---
7Description: Fix remotely exploitable DoS. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10396
8Source: vendor; https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=51682
9Bug-debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=867986
10
11Index: pkg-ipsec-tools/src/racoon/isakmp_frag.c
12===================================================================
13--- pkg-ipsec-tools.orig/src/racoon/isakmp_frag.c
14+++ pkg-ipsec-tools/src/racoon/isakmp_frag.c
15@@ -1,4 +1,4 @@
16-/* $NetBSD: isakmp_frag.c,v 1.5 2009/04/22 11:24:20 tteras Exp $ */
17+/* $NetBSD: isakmp_frag.c,v 1.5.36.1 2017/04/21 16:50:42 bouyer Exp $ */
18
19 /* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */
20
21@@ -173,6 +173,43 @@ vendorid_frag_cap(gen)
22 return ntohl(hp[MD5_DIGEST_LENGTH / sizeof(*hp)]);
23 }
24
25+static int
26+isakmp_frag_insert(struct ph1handle *iph1, struct isakmp_frag_item *item)
27+{
28+ struct isakmp_frag_item *pitem = NULL;
29+ struct isakmp_frag_item *citem = iph1->frag_chain;
30+
31+ /* no frag yet, just insert at beginning of list */
32+ if (iph1->frag_chain == NULL) {
33+ iph1->frag_chain = item;
34+ return 0;
35+ }
36+
37+ do {
38+ /* duplicate fragment number, abort (CVE-2016-10396) */
39+ if (citem->frag_num == item->frag_num)
40+ return -1;
41+
42+ /* need to insert before current item */
43+ if (citem->frag_num > item->frag_num) {
44+ if (pitem != NULL)
45+ pitem->frag_next = item;
46+ else
47+ /* insert at the beginning of the list */
48+ iph1->frag_chain = item;
49+ item->frag_next = citem;
50+ return 0;
51+ }
52+
53+ pitem = citem;
54+ citem = citem->frag_next;
55+ } while (citem != NULL);
56+
57+ /* we reached the end of the list, insert */
58+ pitem->frag_next = item;
59+ return 0;
60+}
61+
62 int
63 isakmp_frag_extract(iph1, msg)
64 struct ph1handle *iph1;
65@@ -224,39 +261,43 @@ isakmp_frag_extract(iph1, msg)
66 item->frag_next = NULL;
67 item->frag_packet = buf;
68
69- /* Look for the last frag while inserting the new item in the chain */
70- if (item->frag_last)
71- last_frag = item->frag_num;
72+ /* Check for the last frag before inserting the new item in the chain */
73+ if (item->frag_last) {
74+ /* if we have the last fragment, indices must match */
75+ if (iph1->frag_last_index != 0 &&
76+ item->frag_last != iph1->frag_last_index) {
77+ plog(LLV_ERROR, LOCATION, NULL,
78+ "Repeated last fragment index mismatch\n");
79+ racoon_free(item);
80+ vfree(buf);
81+ return -1;
82+ }
83
84- if (iph1->frag_chain == NULL) {
85- iph1->frag_chain = item;
86- } else {
87- struct isakmp_frag_item *current;
88+ last_frag = iph1->frag_last_index = item->frag_num;
89+ }
90
91- current = iph1->frag_chain;
92- while (current->frag_next) {
93- if (current->frag_last)
94- last_frag = item->frag_num;
95- current = current->frag_next;
96- }
97- current->frag_next = item;
98+ /* insert fragment into chain */
99+ if (isakmp_frag_insert(iph1, item) == -1) {
100+ plog(LLV_ERROR, LOCATION, NULL,
101+ "Repeated fragment index mismatch\n");
102+ racoon_free(item);
103+ vfree(buf);
104+ return -1;
105 }
106
107- /* If we saw the last frag, check if the chain is complete */
108+ /* If we saw the last frag, check if the chain is complete
109+ * we have a sorted list now, so just walk through */
110 if (last_frag != 0) {
111+ item = iph1->frag_chain;
112 for (i = 1; i <= last_frag; i++) {
113- item = iph1->frag_chain;
114- do {
115- if (item->frag_num == i)
116- break;
117- item = item->frag_next;
118- } while (item != NULL);
119-
120+ if (item->frag_num != i)
121+ break;
122+ item = item->frag_next;
123 if (item == NULL) /* Not found */
124 break;
125 }
126
127- if (item != NULL) /* It is complete */
128+ if (i > last_frag) /* It is complete */
129 return 1;
130 }
131
132@@ -291,15 +332,9 @@ isakmp_frag_reassembly(iph1)
133 }
134 data = buf->v;
135
136+ item = iph1->frag_chain;
137 for (i = 1; i <= frag_count; i++) {
138- item = iph1->frag_chain;
139- do {
140- if (item->frag_num == i)
141- break;
142- item = item->frag_next;
143- } while (item != NULL);
144-
145- if (item == NULL) {
146+ if (item->frag_num != i) {
147 plog(LLV_ERROR, LOCATION, NULL,
148 "Missing fragment #%d\n", i);
149 vfree(buf);
150@@ -308,6 +343,7 @@ isakmp_frag_reassembly(iph1)
151 }
152 memcpy(data, item->frag_packet->v, item->frag_packet->l);
153 data += item->frag_packet->l;
154+ item = item->frag_next;
155 }
156
157 out:
158Index: pkg-ipsec-tools/src/racoon/isakmp_inf.c
159===================================================================
160--- pkg-ipsec-tools.orig/src/racoon/isakmp_inf.c
161+++ pkg-ipsec-tools/src/racoon/isakmp_inf.c
162@@ -720,6 +720,7 @@ isakmp_info_send_nx(isakmp, remote, loca
163 #endif
164 #ifdef ENABLE_FRAG
165 iph1->frag = 0;
166+ iph1->frag_last_index = 0;
167 iph1->frag_chain = NULL;
168 #endif
169
170Index: pkg-ipsec-tools/src/racoon/isakmp.c
171===================================================================
172--- pkg-ipsec-tools.orig/src/racoon/isakmp.c
173+++ pkg-ipsec-tools/src/racoon/isakmp.c
174@@ -1072,6 +1072,7 @@ isakmp_ph1begin_i(rmconf, remote, local)
175 iph1->frag = 1;
176 else
177 iph1->frag = 0;
178+ iph1->frag_last_index = 0;
179 iph1->frag_chain = NULL;
180 #endif
181 iph1->approval = NULL;
182@@ -1176,6 +1177,7 @@ isakmp_ph1begin_r(msg, remote, local, et
183 #endif
184 #ifdef ENABLE_FRAG
185 iph1->frag = 0;
186+ iph1->frag_last_index = 0;
187 iph1->frag_chain = NULL;
188 #endif
189 iph1->approval = NULL;
190Index: pkg-ipsec-tools/src/racoon/handler.h
191===================================================================
192--- pkg-ipsec-tools.orig/src/racoon/handler.h
193+++ pkg-ipsec-tools/src/racoon/handler.h
194@@ -1,4 +1,4 @@
195-/* $NetBSD: handler.h,v 1.25 2010/11/17 10:40:41 tteras Exp $ */
196+/* $NetBSD: handler.h,v 1.26 2017/01/24 19:23:56 christos Exp $ */
197
198 /* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */
199
200@@ -141,6 +141,7 @@ struct ph1handle {
201 #endif
202 #ifdef ENABLE_FRAG
203 int frag; /* IKE phase 1 fragmentation */
204+ int frag_last_index;
205 struct isakmp_frag_item *frag_chain; /* Received fragments */
206 #endif
207