# HG changeset patch # User Rich Burridge # Date 1416361177 28800 # Node ID b125568c3ea5ec6ad29244a1c1dcb36d2c87b3e8 # Parent 679bd7a4e94d7e3a06ad85dd6a3d2048567e8a0e 20047275 problem in LIBRARY/CURL diff -r 679bd7a4e94d -r b125568c3ea5 components/curl/patches/017-CVE-2014-3707.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/curl/patches/017-CVE-2014-3707.patch Tue Nov 18 17:39:37 2014 -0800 @@ -0,0 +1,385 @@ +(This is based on the curl patch at: + http://curl.haxx.se/CVE-2014-3707.patch + but adjusted for curl version 7.21.2). + +From 3696fc1ba79d9b34660c44150be5e93ecf87dd9e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 17 Oct 2014 12:59:32 +0200 +Subject: [PATCH] curl_easy_duphandle: CURLOPT_COPYPOSTFIELDS read out of + bounds + +When duplicating a handle, the data to post was duplicated using +strdup() when it could be binary and contain zeroes and it was not even +zero terminated! This caused read out of bounds crashes/segfaults. + +Since the lib/strdup.c file no longer is easily shared with the curl +tool with this change, it now uses its own version instead. + +Bug: http://curl.haxx.se/docs/adv_20141105.html +CVE: CVE-2014-3707 +Reported-By: Symeon Paraschoudis +--- + lib/formdata.c | 52 +++++++++------------------------------------------- + lib/strdup.c | 32 +++++++++++++++++++++++++++----- + lib/strdup.h | 3 ++- + lib/url.c | 22 +++++++++++++++++----- + lib/urldata.h | 11 +++++++++-- + src/Makefile.inc | 4 ++-- + src/tool_setup.h | 5 ++--- + src/tool_strdup.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + src/tool_strdup.h | 30 ++++++++++++++++++++++++++++++ + 9 files changed, 145 insertions(+), 61 deletions(-) + create mode 100644 src/tool_strdup.c + create mode 100644 src/tool_strdup.h + +--- lib/formdata.c.orig 2014-11-18 03:29:06.861398190 -0800 ++++ lib/formdata.c 2014-11-18 03:33:25.634942129 -0800 +@@ -123,6 +123,7 @@ + #include "curl_rand.h" + #include "strequal.h" + #include "curl_memory.h" ++#include "strdup.h" + + #define _MPRINTF_REPLACE /* use our functions only */ + #include +@@ -302,46 +303,6 @@ + + /*************************************************************************** + * +- * memdup() +- * +- * Copies the 'source' data to a newly allocated buffer buffer (that is +- * returned). Uses buffer_length if not null, else uses strlen to determine +- * the length of the buffer to be copied +- * +- * Returns the new pointer or NULL on failure. +- * +- ***************************************************************************/ +-static char *memdup(const char *src, size_t buffer_length) +-{ +- size_t length; +- bool add = FALSE; +- char *buffer; +- +- if(buffer_length) +- length = buffer_length; +- else if(src) { +- length = strlen(src); +- add = TRUE; +- } +- else +- /* no length and a NULL src pointer! */ +- return strdup(""); +- +- buffer = malloc(length+add); +- if(!buffer) +- return NULL; /* fail */ +- +- memcpy(buffer, src, length); +- +- /* if length unknown do null termination */ +- if(add) +- buffer[length] = '\0'; +- +- return buffer; +-} +- +-/*************************************************************************** +- * + * FormAdd() + * + * Stores a formpost parameter and builds the appropriate linked list. +@@ -745,9 +706,12 @@ + (form == first_form) ) { + /* Note that there's small risk that form->name is NULL here if the + app passed in a bad combo, so we better check for that first. */ +- if(form->name) ++ if(form->name) { + /* copy name (without strdup; possibly contains null characters) */ +- form->name = memdup(form->name, form->namelength); ++ form->name = Curl_memdup(form->name, form->namelength? ++ form->namelength: ++ strlen(form->name)+1); ++ } + if(!form->name) { + return_value = CURL_FORMADD_MEMORY; + break; +@@ -758,7 +722,9 @@ + HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | + HTTPPOST_CALLBACK)) ) { + /* copy value (without strdup; possibly contains null characters) */ +- form->value = memdup(form->value, form->contentslength); ++ form->value = Curl_memdup(form->value, form->contentslength? ++ form->contentslength: ++ strlen(form->value)+1); + if(!form->value) { + return_value = CURL_FORMADD_MEMORY; + break; +--- lib/strdup.c.orig 2014-11-18 03:34:47.615106130 -0800 ++++ lib/strdup.c 2014-11-18 03:36:24.540240128 -0800 +@@ -5,7 +5,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms +@@ -22,6 +22,10 @@ + + #include "setup.h" + #include "strdup.h" ++#include "curl_memory.h" ++ ++/* The last #include file should be: */ ++#include "memdebug.h" + + #ifndef HAVE_STRDUP + char *curlx_strdup(const char *str) +@@ -47,3 +51,25 @@ + + } + #endif ++ ++/*************************************************************************** ++ * ++ * Curl_memdup(source, length) ++ * ++ * Copies the 'source' data to a newly allocated buffer (that is ++ * returned). Copies 'length' bytes. ++ * ++ * Returns the new pointer or NULL on failure. ++ * ++ ***************************************************************************/ ++char *Curl_memdup(const char *src, size_t length) ++{ ++ char *buffer = malloc(length); ++ if(!buffer) ++ return NULL; /* fail */ ++ ++ memcpy(buffer, src, length); ++ ++ /* if length unknown do null termination */ ++ return buffer; ++} +--- lib/strdup.h.orig 2014-11-18 03:37:29.169630451 -0800 ++++ lib/strdup.h 2014-11-18 03:37:58.420841595 -0800 +@@ -7,7 +7,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms +@@ -26,5 +26,6 @@ + #ifndef HAVE_STRDUP + extern char *curlx_strdup(const char *str); + #endif ++char *Curl_memdup(const char *src, size_t buffer_length); + + #endif /* HEADER_CURL_STRDUP_H */ +--- lib/url.c.orig 2014-11-18 03:38:54.137970835 -0800 ++++ lib/url.c 2014-11-18 03:43:13.569265802 -0800 +@@ -139,6 +139,7 @@ + #include "rtsp.h" + #include "curl_rtmp.h" + #include "gopher.h" ++#include "strdup.h" + + #define _MPRINTF_REPLACE /* use our functions only */ + #include +@@ -284,8 +285,9 @@ + { + /* Free all dynamic strings stored in the data->set substructure. */ + enum dupstring i; +- for(i=(enum dupstring)0; i < STRING_LAST; i++) ++ for(i=(enum dupstring)0; i < STRING_LAST; i++) { + Curl_safefree(data->set.str[i]); ++ } + } + + static CURLcode setstropt(char **charp, char * s) +@@ -365,14 +367,24 @@ + memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); + + /* duplicate all strings */ +- for(i=(enum dupstring)0; i< STRING_LAST; i++) { ++ for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { + r = setstropt(&dst->set.str[i], src->set.str[i]); + if(r != CURLE_OK) +- break; ++ return r; + } + +- /* If a failure occurred, freeing has to be performed externally. */ +- return r; ++ /* duplicate memory areas pointed to */ ++ i = STRING_COPYPOSTFIELDS; ++ if(src->set.postfieldsize && src->set.str[i]) { ++ /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ ++ dst->set.str[i] = Curl_memdup(src->set.str[i], src->set.postfieldsize); ++ if(!dst->set.str[i]) ++ return CURLE_OUT_OF_MEMORY; ++ /* point to the new copy */ ++ dst->set.postfields = dst->set.str[i]; ++ } ++ ++ return CURLE_OK; + } + + #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) +--- lib/urldata.h.orig 2014-11-18 03:44:28.965134703 -0800 ++++ lib/urldata.h 2014-11-18 03:46:24.706226763 -0800 +@@ -1216,7 +1216,6 @@ + STRING_KRB_LEVEL, /* krb security level */ + STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find + $HOME/.netrc */ +- STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ + STRING_PROXY, /* proxy to use */ + STRING_SET_RANGE, /* range, if used */ + STRING_SET_REFERER, /* custom string for the HTTP referer field */ +@@ -1249,7 +1248,15 @@ + #endif + STRING_MAIL_FROM, + +- /* -- end of strings -- */ ++ /* -- end of zero-terminated strings -- */ ++ ++ STRING_LASTZEROTERMINATED, ++ ++ /* -- below this are pointers to binary data that cannot be strdup'ed. ++ Each such pointer must be added manually to Curl_dupset() --- */ ++ ++ STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ ++ + STRING_LAST /* not used, just an end-of-list marker */ + }; + +--- src/Makefile.inc.orig 2014-11-18 03:47:49.286734214 -0800 ++++ src/Makefile.inc 2014-11-18 03:52:27.133161024 -0800 +@@ -10,15 +10,16 @@ + # libcurl has sources that provide functions named curlx_* that aren't part of + # the official API, but we re-use the code here to avoid duplication. + CURLX_ONES = $(top_srcdir)/lib/strtoofft.c \ +- $(top_srcdir)/lib/strdup.c \ + $(top_srcdir)/lib/rawstr.c \ + $(top_srcdir)/lib/nonblock.c + + CURL_CFILES = main.c hugehelp.c urlglob.c writeout.c writeenv.c \ +- getpass.c homedir.c curlutil.c os-specific.c ++ getpass.c homedir.c curlutil.c os-specific.c \ ++ tool_strdup.c + + CURL_HFILES = hugehelp.h setup.h config-win32.h config-mac.h \ + config-riscos.h urlglob.h version.h os-specific.h \ ++ tool_strdup.h \ + writeout.h writeenv.h getpass.h homedir.h curlutil.h + + curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES) +--- src/setup.h.orig 2014-11-18 03:54:19.162704002 -0800 ++++ src/setup.h 2014-11-18 03:55:05.389517301 -0800 +@@ -7,7 +7,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms +@@ -203,8 +203,7 @@ + #endif + + #ifndef HAVE_STRDUP +-#include "strdup.h" +-#define strdup(ptr) curlx_strdup(ptr) ++# include "tool_strdup.h" + #endif + + /* Define S_ISREG if not defined by system headers, f.e. MSVC */ +--- src/tool_strdup.c.orig 2014-11-18 03:56:00.122473188 -0800 ++++ src/tool_strdup.c 2014-11-18 03:57:10.023119420 -0800 +@@ -0,0 +1,47 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at http://curl.haxx.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ ***************************************************************************/ ++#include "strdup.h" ++ ++#ifndef HAVE_STRDUP ++char *strdup(const char *str) ++{ ++ size_t len; ++ char *newstr; ++ ++ if(!str) ++ return (char *)NULL; ++ ++ len = strlen(str); ++ ++ if(len >= ((size_t)-1) / sizeof(char)) ++ return (char *)NULL; ++ ++ newstr = malloc((len+1)*sizeof(char)); ++ if(!newstr) ++ return (char *)NULL; ++ ++ memcpy(newstr,str,(len+1)*sizeof(char)); ++ ++ return newstr; ++ ++} ++#endif +--- src/tool_strdup.h.orig 2014-11-18 03:57:45.315222626 -0800 ++++ src/tool_strdup.h 2014-11-18 03:58:13.983815925 -0800 +@@ -0,0 +1,30 @@ ++#ifndef HEADER_TOOL_STRDUP_H ++#define HEADER_TOOL_STRDUP_H ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. ++ * ++ * This software is licensed as described in the file COPYING, which ++ * you should have received as part of this distribution. The terms ++ * are also available at http://curl.haxx.se/docs/copyright.html. ++ * ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell ++ * copies of the Software, and permit persons to whom the Software is ++ * furnished to do so, under the terms of the COPYING file. ++ * ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY ++ * KIND, either express or implied. ++ * ++ ***************************************************************************/ ++#include "tool_setup.h" ++ ++#ifndef HAVE_STRDUP ++extern char *strdup(const char *str); ++#endif ++ ++#endif /* HEADER_TOOL_STRDUP_H */