aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2016-10-08 12:50:42 +0200
committerDaniel Stenberg <daniel@haxx.se>2016-10-08 13:00:45 +0200
commit9885c9508ec757f7f658dab11658e4a3e643a420 (patch)
tree35af961981ab069167b9d9285a5da3fa10bac7d9
parentf74baaf3b3c8a4297d40322bf0ea9a6e136a3a73 (diff)
formpost: avoid silent snprintf() truncation
The previous use of snprintf() could make libcurl silently truncate some input data and not report that back on overly large input, which could make data get sent over the network in a bad format. Example: $ curl --form 'a=b' -H "Content-Type: $(perl -e 'print "A"x4100')"
-rw-r--r--lib/formdata.c35
-rw-r--r--lib/formdata.h1
2 files changed, 26 insertions, 10 deletions
diff --git a/lib/formdata.c b/lib/formdata.c
index 13901b330..ae75fe175 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -845,16 +845,23 @@ static CURLcode AddFormData(struct FormData **formp,
goto error;
}
#endif
+ if(type != FORM_DATAMEM) {
+ newform->line = malloc((size_t)length+1);
+ if(!newform->line) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto error;
+ }
+ alloc2 = newform->line;
+ memcpy(newform->line, line, (size_t)length);
- newform->line = malloc((size_t)length+1);
- if(!newform->line) {
- result = CURLE_OUT_OF_MEMORY;
- goto error;
+ /* zero terminate for easier debugging */
+ newform->line[(size_t)length]=0;
+ }
+ else {
+ newform->line = (char *)line;
+ type = FORM_DATA; /* in all other aspects this is just FORM_DATA */
}
- alloc2 = newform->line;
- memcpy(newform->line, line, (size_t)length);
newform->length = (size_t)length;
- newform->line[(size_t)length]=0; /* zero terminate for easier debugging */
}
else
/* For callbacks and files we don't have any actual data so we just keep a
@@ -907,13 +914,21 @@ static CURLcode AddFormDataf(struct FormData **formp,
curl_off_t *size,
const char *fmt, ...)
{
- char s[4096];
+ char *s;
+ CURLcode result;
va_list ap;
va_start(ap, fmt);
- vsnprintf(s, sizeof(s), fmt, ap);
+ s = curl_mvaprintf(fmt, ap);
va_end(ap);
- return AddFormData(formp, FORM_DATA, s, 0, size);
+ if(!s)
+ return CURLE_OUT_OF_MEMORY;
+
+ result = AddFormData(formp, FORM_DATAMEM, s, 0, size);
+ if(result)
+ free(s);
+
+ return result;
}
/*
diff --git a/lib/formdata.h b/lib/formdata.h
index 6eb7c6c9e..200470b50 100644
--- a/lib/formdata.h
+++ b/lib/formdata.h
@@ -23,6 +23,7 @@
***************************************************************************/
enum formtype {
+ FORM_DATAMEM, /* already allocated FORM_DATA memory */
FORM_DATA, /* form metadata (convert to network encoding if necessary) */
FORM_CONTENT, /* form content (never convert) */
FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback