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
This commit is contained in:
Daniel Stenberg
2014-10-17 12:59:32 +02:00
parent d997c8b2f6
commit b387560692
9 changed files with 145 additions and 61 deletions

View File

@@ -36,6 +36,7 @@
#include "strequal.h"
#include "curl_memory.h"
#include "sendf.h"
#include "strdup.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -208,46 +209,6 @@ static const char *ContentTypeForFilename(const char *filename,
return contenttype;
}
/***************************************************************************
*
* 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()
@@ -678,9 +639,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
(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;
@@ -691,7 +655,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
HTTPPOST_CALLBACK)) && form->value) {
/* 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;