|
1 (This is based on the curl patch at: |
|
2 http://curl.haxx.se/CVE-2014-3707.patch |
|
3 but adjusted for curl version 7.21.2). |
|
4 |
|
5 From 3696fc1ba79d9b34660c44150be5e93ecf87dd9e Mon Sep 17 00:00:00 2001 |
|
6 From: Daniel Stenberg <[email protected]> |
|
7 Date: Fri, 17 Oct 2014 12:59:32 +0200 |
|
8 Subject: [PATCH] curl_easy_duphandle: CURLOPT_COPYPOSTFIELDS read out of |
|
9 bounds |
|
10 |
|
11 When duplicating a handle, the data to post was duplicated using |
|
12 strdup() when it could be binary and contain zeroes and it was not even |
|
13 zero terminated! This caused read out of bounds crashes/segfaults. |
|
14 |
|
15 Since the lib/strdup.c file no longer is easily shared with the curl |
|
16 tool with this change, it now uses its own version instead. |
|
17 |
|
18 Bug: http://curl.haxx.se/docs/adv_20141105.html |
|
19 CVE: CVE-2014-3707 |
|
20 Reported-By: Symeon Paraschoudis |
|
21 --- |
|
22 lib/formdata.c | 52 +++++++++------------------------------------------- |
|
23 lib/strdup.c | 32 +++++++++++++++++++++++++++----- |
|
24 lib/strdup.h | 3 ++- |
|
25 lib/url.c | 22 +++++++++++++++++----- |
|
26 lib/urldata.h | 11 +++++++++-- |
|
27 src/Makefile.inc | 4 ++-- |
|
28 src/tool_setup.h | 5 ++--- |
|
29 src/tool_strdup.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ |
|
30 src/tool_strdup.h | 30 ++++++++++++++++++++++++++++++ |
|
31 9 files changed, 145 insertions(+), 61 deletions(-) |
|
32 create mode 100644 src/tool_strdup.c |
|
33 create mode 100644 src/tool_strdup.h |
|
34 |
|
35 --- lib/formdata.c.orig 2014-11-18 03:29:06.861398190 -0800 |
|
36 +++ lib/formdata.c 2014-11-18 03:33:25.634942129 -0800 |
|
37 @@ -123,6 +123,7 @@ |
|
38 #include "curl_rand.h" |
|
39 #include "strequal.h" |
|
40 #include "curl_memory.h" |
|
41 +#include "strdup.h" |
|
42 |
|
43 #define _MPRINTF_REPLACE /* use our functions only */ |
|
44 #include <curl/mprintf.h> |
|
45 @@ -302,46 +303,6 @@ |
|
46 |
|
47 /*************************************************************************** |
|
48 * |
|
49 - * memdup() |
|
50 - * |
|
51 - * Copies the 'source' data to a newly allocated buffer buffer (that is |
|
52 - * returned). Uses buffer_length if not null, else uses strlen to determine |
|
53 - * the length of the buffer to be copied |
|
54 - * |
|
55 - * Returns the new pointer or NULL on failure. |
|
56 - * |
|
57 - ***************************************************************************/ |
|
58 -static char *memdup(const char *src, size_t buffer_length) |
|
59 -{ |
|
60 - size_t length; |
|
61 - bool add = FALSE; |
|
62 - char *buffer; |
|
63 - |
|
64 - if(buffer_length) |
|
65 - length = buffer_length; |
|
66 - else if(src) { |
|
67 - length = strlen(src); |
|
68 - add = TRUE; |
|
69 - } |
|
70 - else |
|
71 - /* no length and a NULL src pointer! */ |
|
72 - return strdup(""); |
|
73 - |
|
74 - buffer = malloc(length+add); |
|
75 - if(!buffer) |
|
76 - return NULL; /* fail */ |
|
77 - |
|
78 - memcpy(buffer, src, length); |
|
79 - |
|
80 - /* if length unknown do null termination */ |
|
81 - if(add) |
|
82 - buffer[length] = '\0'; |
|
83 - |
|
84 - return buffer; |
|
85 -} |
|
86 - |
|
87 -/*************************************************************************** |
|
88 - * |
|
89 * FormAdd() |
|
90 * |
|
91 * Stores a formpost parameter and builds the appropriate linked list. |
|
92 @@ -745,9 +706,12 @@ |
|
93 (form == first_form) ) { |
|
94 /* Note that there's small risk that form->name is NULL here if the |
|
95 app passed in a bad combo, so we better check for that first. */ |
|
96 - if(form->name) |
|
97 + if(form->name) { |
|
98 /* copy name (without strdup; possibly contains null characters) */ |
|
99 - form->name = memdup(form->name, form->namelength); |
|
100 + form->name = Curl_memdup(form->name, form->namelength? |
|
101 + form->namelength: |
|
102 + strlen(form->name)+1); |
|
103 + } |
|
104 if(!form->name) { |
|
105 return_value = CURL_FORMADD_MEMORY; |
|
106 break; |
|
107 @@ -758,7 +722,9 @@ |
|
108 HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | |
|
109 HTTPPOST_CALLBACK)) ) { |
|
110 /* copy value (without strdup; possibly contains null characters) */ |
|
111 - form->value = memdup(form->value, form->contentslength); |
|
112 + form->value = Curl_memdup(form->value, form->contentslength? |
|
113 + form->contentslength: |
|
114 + strlen(form->value)+1); |
|
115 if(!form->value) { |
|
116 return_value = CURL_FORMADD_MEMORY; |
|
117 break; |
|
118 --- lib/strdup.c.orig 2014-11-18 03:34:47.615106130 -0800 |
|
119 +++ lib/strdup.c 2014-11-18 03:36:24.540240128 -0800 |
|
120 @@ -5,7 +5,7 @@ |
|
121 * | (__| |_| | _ <| |___ |
|
122 * \___|\___/|_| \_\_____| |
|
123 * |
|
124 - * Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al. |
|
125 + * Copyright (C) 1998 - 2014, Daniel Stenberg, <[email protected]>, et al. |
|
126 * |
|
127 * This software is licensed as described in the file COPYING, which |
|
128 * you should have received as part of this distribution. The terms |
|
129 @@ -22,6 +22,10 @@ |
|
130 |
|
131 #include "setup.h" |
|
132 #include "strdup.h" |
|
133 +#include "curl_memory.h" |
|
134 + |
|
135 +/* The last #include file should be: */ |
|
136 +#include "memdebug.h" |
|
137 |
|
138 #ifndef HAVE_STRDUP |
|
139 char *curlx_strdup(const char *str) |
|
140 @@ -47,3 +51,25 @@ |
|
141 |
|
142 } |
|
143 #endif |
|
144 + |
|
145 +/*************************************************************************** |
|
146 + * |
|
147 + * Curl_memdup(source, length) |
|
148 + * |
|
149 + * Copies the 'source' data to a newly allocated buffer (that is |
|
150 + * returned). Copies 'length' bytes. |
|
151 + * |
|
152 + * Returns the new pointer or NULL on failure. |
|
153 + * |
|
154 + ***************************************************************************/ |
|
155 +char *Curl_memdup(const char *src, size_t length) |
|
156 +{ |
|
157 + char *buffer = malloc(length); |
|
158 + if(!buffer) |
|
159 + return NULL; /* fail */ |
|
160 + |
|
161 + memcpy(buffer, src, length); |
|
162 + |
|
163 + /* if length unknown do null termination */ |
|
164 + return buffer; |
|
165 +} |
|
166 --- lib/strdup.h.orig 2014-11-18 03:37:29.169630451 -0800 |
|
167 +++ lib/strdup.h 2014-11-18 03:37:58.420841595 -0800 |
|
168 @@ -7,7 +7,7 @@ |
|
169 * | (__| |_| | _ <| |___ |
|
170 * \___|\___/|_| \_\_____| |
|
171 * |
|
172 - * Copyright (C) 1998 - 2010, Daniel Stenberg, <[email protected]>, et al. |
|
173 + * Copyright (C) 1998 - 2014, Daniel Stenberg, <[email protected]>, et al. |
|
174 * |
|
175 * This software is licensed as described in the file COPYING, which |
|
176 * you should have received as part of this distribution. The terms |
|
177 @@ -26,5 +26,6 @@ |
|
178 #ifndef HAVE_STRDUP |
|
179 extern char *curlx_strdup(const char *str); |
|
180 #endif |
|
181 +char *Curl_memdup(const char *src, size_t buffer_length); |
|
182 |
|
183 #endif /* HEADER_CURL_STRDUP_H */ |
|
184 --- lib/url.c.orig 2014-11-18 03:38:54.137970835 -0800 |
|
185 +++ lib/url.c 2014-11-18 03:43:13.569265802 -0800 |
|
186 @@ -139,6 +139,7 @@ |
|
187 #include "rtsp.h" |
|
188 #include "curl_rtmp.h" |
|
189 #include "gopher.h" |
|
190 +#include "strdup.h" |
|
191 |
|
192 #define _MPRINTF_REPLACE /* use our functions only */ |
|
193 #include <curl/mprintf.h> |
|
194 @@ -284,8 +285,9 @@ |
|
195 { |
|
196 /* Free all dynamic strings stored in the data->set substructure. */ |
|
197 enum dupstring i; |
|
198 - for(i=(enum dupstring)0; i < STRING_LAST; i++) |
|
199 + for(i=(enum dupstring)0; i < STRING_LAST; i++) { |
|
200 Curl_safefree(data->set.str[i]); |
|
201 + } |
|
202 } |
|
203 |
|
204 static CURLcode setstropt(char **charp, char * s) |
|
205 @@ -365,14 +367,24 @@ |
|
206 memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); |
|
207 |
|
208 /* duplicate all strings */ |
|
209 - for(i=(enum dupstring)0; i< STRING_LAST; i++) { |
|
210 + for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { |
|
211 r = setstropt(&dst->set.str[i], src->set.str[i]); |
|
212 if(r != CURLE_OK) |
|
213 - break; |
|
214 + return r; |
|
215 } |
|
216 |
|
217 - /* If a failure occurred, freeing has to be performed externally. */ |
|
218 - return r; |
|
219 + /* duplicate memory areas pointed to */ |
|
220 + i = STRING_COPYPOSTFIELDS; |
|
221 + if(src->set.postfieldsize && src->set.str[i]) { |
|
222 + /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ |
|
223 + dst->set.str[i] = Curl_memdup(src->set.str[i], src->set.postfieldsize); |
|
224 + if(!dst->set.str[i]) |
|
225 + return CURLE_OUT_OF_MEMORY; |
|
226 + /* point to the new copy */ |
|
227 + dst->set.postfields = dst->set.str[i]; |
|
228 + } |
|
229 + |
|
230 + return CURLE_OK; |
|
231 } |
|
232 |
|
233 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) |
|
234 --- lib/urldata.h.orig 2014-11-18 03:44:28.965134703 -0800 |
|
235 +++ lib/urldata.h 2014-11-18 03:46:24.706226763 -0800 |
|
236 @@ -1216,7 +1216,6 @@ |
|
237 STRING_KRB_LEVEL, /* krb security level */ |
|
238 STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find |
|
239 $HOME/.netrc */ |
|
240 - STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ |
|
241 STRING_PROXY, /* proxy to use */ |
|
242 STRING_SET_RANGE, /* range, if used */ |
|
243 STRING_SET_REFERER, /* custom string for the HTTP referer field */ |
|
244 @@ -1249,7 +1248,15 @@ |
|
245 #endif |
|
246 STRING_MAIL_FROM, |
|
247 |
|
248 - /* -- end of strings -- */ |
|
249 + /* -- end of zero-terminated strings -- */ |
|
250 + |
|
251 + STRING_LASTZEROTERMINATED, |
|
252 + |
|
253 + /* -- below this are pointers to binary data that cannot be strdup'ed. |
|
254 + Each such pointer must be added manually to Curl_dupset() --- */ |
|
255 + |
|
256 + STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ |
|
257 + |
|
258 STRING_LAST /* not used, just an end-of-list marker */ |
|
259 }; |
|
260 |
|
261 --- src/Makefile.inc.orig 2014-11-18 03:47:49.286734214 -0800 |
|
262 +++ src/Makefile.inc 2014-11-18 03:52:27.133161024 -0800 |
|
263 @@ -10,15 +10,16 @@ |
|
264 # libcurl has sources that provide functions named curlx_* that aren't part of |
|
265 # the official API, but we re-use the code here to avoid duplication. |
|
266 CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \ |
|
267 - $(top_srcdir)/lib/strdup.c \ |
|
268 $(top_srcdir)/lib/rawstr.c \ |
|
269 $(top_srcdir)/lib/nonblock.c |
|
270 |
|
271 CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \ |
|
272 - getpass.c homedir.c curlutil.c os-specific.c |
|
273 + getpass.c homedir.c curlutil.c os-specific.c \ |
|
274 + tool_strdup.c |
|
275 |
|
276 CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \ |
|
277 config-riscos.h urlglob.h version.h os-specific.h \ |
|
278 + tool_strdup.h \ |
|
279 writeout.h writeenv.h getpass.h homedir.h curlutil.h |
|
280 |
|
281 curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES) |
|
282 --- src/setup.h.orig 2014-11-18 03:54:19.162704002 -0800 |
|
283 +++ src/setup.h 2014-11-18 03:55:05.389517301 -0800 |
|
284 @@ -7,7 +7,7 @@ |
|
285 * | (__| |_| | _ <| |___ |
|
286 * \___|\___/|_| \_\_____| |
|
287 * |
|
288 - * Copyright (C) 1998 - 2010, Daniel Stenberg, <[email protected]>, et al. |
|
289 + * Copyright (C) 1998 - 2014, Daniel Stenberg, <[email protected]>, et al. |
|
290 * |
|
291 * This software is licensed as described in the file COPYING, which |
|
292 * you should have received as part of this distribution. The terms |
|
293 @@ -203,8 +203,7 @@ |
|
294 #endif |
|
295 |
|
296 #ifndef HAVE_STRDUP |
|
297 -#include "strdup.h" |
|
298 -#define strdup(ptr) curlx_strdup(ptr) |
|
299 +# include "tool_strdup.h" |
|
300 #endif |
|
301 |
|
302 /* Define S_ISREG if not defined by system headers, f.e. MSVC */ |
|
303 --- src/tool_strdup.c.orig 2014-11-18 03:56:00.122473188 -0800 |
|
304 +++ src/tool_strdup.c 2014-11-18 03:57:10.023119420 -0800 |
|
305 @@ -0,0 +1,47 @@ |
|
306 +/*************************************************************************** |
|
307 + * _ _ ____ _ |
|
308 + * Project ___| | | | _ \| | |
|
309 + * / __| | | | |_) | | |
|
310 + * | (__| |_| | _ <| |___ |
|
311 + * \___|\___/|_| \_\_____| |
|
312 + * |
|
313 + * Copyright (C) 1998 - 2014, Daniel Stenberg, <[email protected]>, et al. |
|
314 + * |
|
315 + * This software is licensed as described in the file COPYING, which |
|
316 + * you should have received as part of this distribution. The terms |
|
317 + * are also available at http://curl.haxx.se/docs/copyright.html. |
|
318 + * |
|
319 + * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
|
320 + * copies of the Software, and permit persons to whom the Software is |
|
321 + * furnished to do so, under the terms of the COPYING file. |
|
322 + * |
|
323 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
|
324 + * KIND, either express or implied. |
|
325 + * |
|
326 + ***************************************************************************/ |
|
327 +#include "strdup.h" |
|
328 + |
|
329 +#ifndef HAVE_STRDUP |
|
330 +char *strdup(const char *str) |
|
331 +{ |
|
332 + size_t len; |
|
333 + char *newstr; |
|
334 + |
|
335 + if(!str) |
|
336 + return (char *)NULL; |
|
337 + |
|
338 + len = strlen(str); |
|
339 + |
|
340 + if(len >= ((size_t)-1) / sizeof(char)) |
|
341 + return (char *)NULL; |
|
342 + |
|
343 + newstr = malloc((len+1)*sizeof(char)); |
|
344 + if(!newstr) |
|
345 + return (char *)NULL; |
|
346 + |
|
347 + memcpy(newstr,str,(len+1)*sizeof(char)); |
|
348 + |
|
349 + return newstr; |
|
350 + |
|
351 +} |
|
352 +#endif |
|
353 --- src/tool_strdup.h.orig 2014-11-18 03:57:45.315222626 -0800 |
|
354 +++ src/tool_strdup.h 2014-11-18 03:58:13.983815925 -0800 |
|
355 @@ -0,0 +1,30 @@ |
|
356 +#ifndef HEADER_TOOL_STRDUP_H |
|
357 +#define HEADER_TOOL_STRDUP_H |
|
358 +/*************************************************************************** |
|
359 + * _ _ ____ _ |
|
360 + * Project ___| | | | _ \| | |
|
361 + * / __| | | | |_) | | |
|
362 + * | (__| |_| | _ <| |___ |
|
363 + * \___|\___/|_| \_\_____| |
|
364 + * |
|
365 + * Copyright (C) 1998 - 2014, Daniel Stenberg, <[email protected]>, et al. |
|
366 + * |
|
367 + * This software is licensed as described in the file COPYING, which |
|
368 + * you should have received as part of this distribution. The terms |
|
369 + * are also available at http://curl.haxx.se/docs/copyright.html. |
|
370 + * |
|
371 + * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
|
372 + * copies of the Software, and permit persons to whom the Software is |
|
373 + * furnished to do so, under the terms of the COPYING file. |
|
374 + * |
|
375 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
|
376 + * KIND, either express or implied. |
|
377 + * |
|
378 + ***************************************************************************/ |
|
379 +#include "tool_setup.h" |
|
380 + |
|
381 +#ifndef HAVE_STRDUP |
|
382 +extern char *strdup(const char *str); |
|
383 +#endif |
|
384 + |
|
385 +#endif /* HEADER_TOOL_STRDUP_H */ |