mirror of
https://github.com/curl/curl.git
synced 2026-08-25 03:43:31 +03:00
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
This commit is contained in:
parent
d6c8def82a
commit
f1c26efcbf
5 changed files with 36 additions and 14 deletions
|
|
@ -545,7 +545,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||||
GetStr(&config->oauth_bearer, nextarg);
|
GetStr(&config->oauth_bearer, nextarg);
|
||||||
break;
|
break;
|
||||||
case 'c': /* connect-timeout */
|
case 'c': /* connect-timeout */
|
||||||
err = str2udouble(&config->connecttimeout, nextarg);
|
err = str2udouble(&config->connecttimeout, nextarg,
|
||||||
|
LONG_MAX/1000);
|
||||||
if(err)
|
if(err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1047,7 +1048,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
case 'R': /* --expect100-timeout */
|
case 'R': /* --expect100-timeout */
|
||||||
err = str2udouble(&config->expect100timeout, nextarg);
|
err = str2udouble(&config->expect100timeout, nextarg, LONG_MAX/1000);
|
||||||
if(err)
|
if(err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1713,7 +1714,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
/* specified max time */
|
/* specified max time */
|
||||||
err = str2udouble(&config->timeout, nextarg);
|
err = str2udouble(&config->timeout, nextarg, LONG_MAX/1000);
|
||||||
if(err)
|
if(err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ typedef enum {
|
||||||
PARAM_NO_MEM,
|
PARAM_NO_MEM,
|
||||||
PARAM_NEXT_OPERATION,
|
PARAM_NEXT_OPERATION,
|
||||||
PARAM_NO_PREFIX,
|
PARAM_NO_PREFIX,
|
||||||
|
PARAM_NUMBER_TOO_LARGE,
|
||||||
PARAM_LAST
|
PARAM_LAST
|
||||||
} ParameterError;
|
} ParameterError;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ const char *param2text(int res)
|
||||||
return "out of memory";
|
return "out of memory";
|
||||||
case PARAM_NO_PREFIX:
|
case PARAM_NO_PREFIX:
|
||||||
return "the given option can't be reversed with a --no- prefix";
|
return "the given option can't be reversed with a --no- prefix";
|
||||||
|
case PARAM_NUMBER_TOO_LARGE:
|
||||||
|
return "too large number";
|
||||||
default:
|
default:
|
||||||
return "unknown error";
|
return "unknown error";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
|
|
@ -164,7 +164,11 @@ ParameterError str2num(long *val, const char *str)
|
||||||
{
|
{
|
||||||
if(str) {
|
if(str) {
|
||||||
char *endptr;
|
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))) {
|
if((endptr != str) && (endptr == str + strlen(str))) {
|
||||||
*val = num;
|
*val = num;
|
||||||
return PARAM_OK; /* Ok */
|
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
|
* Parse the string and write the double in the given address. Return PARAM_OK
|
||||||
* on success, otherwise a parameter specific error enum.
|
* 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
|
* 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
|
* getparameter a lot, we must check it for NULL before accessing the str
|
||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ParameterError str2double(double *val, const char *str)
|
static ParameterError str2double(double *val, const char *str, long max)
|
||||||
{
|
{
|
||||||
if(str) {
|
if(str) {
|
||||||
char *endptr;
|
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)val > max) {
|
||||||
|
/* too large */
|
||||||
|
return PARAM_NUMBER_TOO_LARGE;
|
||||||
|
}
|
||||||
if((endptr != str) && (endptr == str + strlen(str))) {
|
if((endptr != str) && (endptr == str + strlen(str))) {
|
||||||
*val = num;
|
*val = num;
|
||||||
return PARAM_OK; /* Ok */
|
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
|
* 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!
|
* 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
|
* 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
|
* getparameter a lot, we must check it for NULL before accessing the str
|
||||||
* data.
|
* 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)
|
if(result != PARAM_OK)
|
||||||
return result;
|
return result;
|
||||||
if(*val < 0)
|
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)
|
#if(CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
|
||||||
*val = curlx_strtoofft(str, &endptr, 0);
|
*val = curlx_strtoofft(str, &endptr, 0);
|
||||||
if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (errno == ERANGE))
|
if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (errno == ERANGE))
|
||||||
return PARAM_BAD_NUMERIC;
|
return PARAM_NUMBER_TOO_LARGE;
|
||||||
#else
|
#else
|
||||||
|
errno = 0;
|
||||||
*val = strtol(str, &endptr, 0);
|
*val = strtol(str, &endptr, 0);
|
||||||
if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
|
if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
|
||||||
return PARAM_BAD_NUMERIC;
|
return PARAM_NUMBER_TOO_LARGE;
|
||||||
#endif
|
#endif
|
||||||
if((endptr != str) && (endptr == str + strlen(str)))
|
if((endptr != str) && (endptr == str + strlen(str)))
|
||||||
return PARAM_OK;
|
return PARAM_OK;
|
||||||
|
|
|
||||||
|
|
@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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 str2num(long *val, const char *str);
|
||||||
ParameterError str2unum(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, long max);
|
||||||
ParameterError str2udouble(double *val, const char *str);
|
|
||||||
|
|
||||||
long proto2num(struct OperationConfig *config, long *val, const char *str);
|
long proto2num(struct OperationConfig *config, long *val, const char *str);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue