summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2017-08-06 20:10:40 +0200
committerDaniel Stenberg <daniel@haxx.se>2017-08-07 09:38:45 +0200
commit5c7455fe7691a18e0f6a85ebe26aae861ccc5284 (patch)
treea9470b75e0d35b584557c9873885ea68a1c54cd5
parent453e7a7a03a2cec749abd3878a48e728c515cca7 (diff)
downloadcurl-5c7455fe7691a18e0f6a85ebe26aae861ccc5284.tar.gz
curl: detect and bail out early on parameter integer overflows
Make the number parser aware of the maximum limit curl accepts for a value and return an error immediately if larger, instead of running an integer overflow later. Fixes #1730 Closes #1736
-rw-r--r--src/tool_getparam.c7
-rw-r--r--src/tool_getparam.h1
-rw-r--r--src/tool_helpers.c2
-rw-r--r--src/tool_paramhlp.c35
-rw-r--r--src/tool_paramhlp.h5
5 files changed, 36 insertions, 14 deletions
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 089d28574..b7ee519b3 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -545,7 +545,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
GetStr(&config->oauth_bearer, nextarg);
break;
case 'c': /* connect-timeout */
- err = str2udouble(&config->connecttimeout, nextarg);
+ err = str2udouble(&config->connecttimeout, nextarg,
+ LONG_MAX/1000);
if(err)
return err;
break;
@@ -1047,7 +1048,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
return err;
break;
case 'R': /* --expect100-timeout */
- err = str2udouble(&config->expect100timeout, nextarg);
+ err = str2udouble(&config->expect100timeout, nextarg, LONG_MAX/1000);
if(err)
return err;
break;
@@ -1713,7 +1714,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;
case 'm':
/* specified max time */
- err = str2udouble(&config->timeout, nextarg);
+ err = str2udouble(&config->timeout, nextarg, LONG_MAX/1000);
if(err)
return err;
break;
diff --git a/src/tool_getparam.h b/src/tool_getparam.h
index 29e158816..2148e4091 100644
--- a/src/tool_getparam.h
+++ b/src/tool_getparam.h
@@ -41,6 +41,7 @@ typedef enum {
PARAM_NO_MEM,
PARAM_NEXT_OPERATION,
PARAM_NO_PREFIX,
+ PARAM_NUMBER_TOO_LARGE,
PARAM_LAST
} ParameterError;
diff --git a/src/tool_helpers.c b/src/tool_helpers.c
index 3d2dbe3ac..b3a9516a8 100644
--- a/src/tool_helpers.c
+++ b/src/tool_helpers.c
@@ -64,6 +64,8 @@ const char *param2text(int res)
return "out of memory";
case PARAM_NO_PREFIX:
return "the given option can't be reversed with a --no- prefix";
+ case PARAM_NUMBER_TOO_LARGE:
+ return "too large number";
default:
return "unknown error";
}
diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c
index ee37931b8..b9dedc989 100644
--- a/src/tool_paramhlp.c
+++ b/src/tool_paramhlp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -164,7 +164,11 @@ ParameterError str2num(long *val, const char *str)
{
if(str) {
char *endptr;
- long num = strtol(str, &endptr, 10);
+ long num;
+ errno = 0;
+ num = strtol(str, &endptr, 10);
+ if(errno == ERANGE)
+ return PARAM_NUMBER_TOO_LARGE;
if((endptr != str) && (endptr == str + strlen(str))) {
*val = num;
return PARAM_OK; /* Ok */
@@ -197,16 +201,27 @@ ParameterError str2unum(long *val, const char *str)
* Parse the string and write the double in the given address. Return PARAM_OK
* on success, otherwise a parameter specific error enum.
*
+ * The 'max' argument is the maximum value allowed, as the numbers are often
+ * multiplied when later used.
+ *
* Since this function gets called with the 'nextarg' pointer from within the
* getparameter a lot, we must check it for NULL before accessing the str
* data.
*/
-ParameterError str2double(double *val, const char *str)
+static ParameterError str2double(double *val, const char *str, long max)
{
if(str) {
char *endptr;
- double num = strtod(str, &endptr);
+ double num;
+ errno = 0;
+ num = strtod(str, &endptr);
+ if(errno == ERANGE)
+ return PARAM_NUMBER_TOO_LARGE;
+ if((long)num > max) {
+ /* too large */
+ return PARAM_NUMBER_TOO_LARGE;
+ }
if((endptr != str) && (endptr == str + strlen(str))) {
*val = num;
return PARAM_OK; /* Ok */
@@ -219,14 +234,17 @@ ParameterError str2double(double *val, const char *str)
* Parse the string and write the double in the given address. Return PARAM_OK
* on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
*
+ * The 'max' argument is the maximum value allowed, as the numbers are often
+ * multiplied when later used.
+ *
* Since this function gets called with the 'nextarg' pointer from within the
* getparameter a lot, we must check it for NULL before accessing the str
* data.
*/
-ParameterError str2udouble(double *val, const char *str)
+ParameterError str2udouble(double *val, const char *str, long max)
{
- ParameterError result = str2double(val, str);
+ ParameterError result = str2double(val, str, max);
if(result != PARAM_OK)
return result;
if(*val < 0)
@@ -384,11 +402,12 @@ ParameterError str2offset(curl_off_t *val, const char *str)
#if(CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
*val = curlx_strtoofft(str, &endptr, 0);
if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (errno == ERANGE))
- return PARAM_BAD_NUMERIC;
+ return PARAM_NUMBER_TOO_LARGE;
#else
+ errno = 0;
*val = strtol(str, &endptr, 0);
if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
- return PARAM_BAD_NUMERIC;
+ return PARAM_NUMBER_TOO_LARGE;
#endif
if((endptr != str) && (endptr == str + strlen(str)))
return PARAM_OK;
diff --git a/src/tool_paramhlp.h b/src/tool_paramhlp.h
index cdfbacf3f..854f52256 100644
--- a/src/tool_paramhlp.h
+++ b/src/tool_paramhlp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -33,8 +33,7 @@ void cleanarg(char *str);
ParameterError str2num(long *val, const char *str);
ParameterError str2unum(long *val, const char *str);
-ParameterError str2double(double *val, const char *str);
-ParameterError str2udouble(double *val, const char *str);
+ParameterError str2udouble(double *val, const char *str, long max);
long proto2num(struct OperationConfig *config, long *val, const char *str);