diff options
author | Daniel Stenberg <daniel@haxx.se> | 2018-11-05 11:57:29 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2018-11-07 11:48:17 +0100 |
commit | 52db54869e628c5b13039ecc2b4757f8eb969834 (patch) | |
tree | 1d2958a5aa7fa1cace4e54c54e0ea92bd2b84883 /src | |
parent | bda4ef417a00c91e3a7829fdba4b0968dd62e497 (diff) | |
download | curl-52db54869e628c5b13039ecc2b4757f8eb969834.tar.gz |
curl: fix --local-port integer overflow
The tool's local port command line range parser didn't check for integer
overflows and could pass "weird" data to libcurl for this option.
libcurl however, has a strict range check for the values so it rejects
anything outside of the accepted range.
Reported-by: Brian Carpenter
Closes #3242
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_cfgable.h | 4 | ||||
-rw-r--r-- | src/tool_getparam.c | 31 | ||||
-rw-r--r-- | src/tool_operate.c | 5 |
3 files changed, 26 insertions, 14 deletions
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index b719fa219..501c96189 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -69,8 +69,8 @@ struct OperationConfig { char *headerfile; char *ftpport; char *iface; - int localport; - int localportrange; + long localport; + long localportrange; unsigned short porttouse; char *range; long low_speed_limit; diff --git a/src/tool_getparam.c b/src/tool_getparam.c index f153a70ac..663c4dd4d 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -935,22 +935,35 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ case 'r': /* --ftp-method (undocumented at this point) */ config->ftp_filemethod = ftpfilemethod(config, nextarg); break; - case 's': /* --local-port */ - rc = sscanf(nextarg, "%d - %d", - &config->localport, - &config->localportrange); - if(!rc) + case 's': { /* --local-port */ + char lrange[7]; /* 16bit base 10 is 5 digits, but we allow 6 so that + this catches overflows, not just truncates */ + char *p = nextarg; + while(ISDIGIT(*p)) + p++; + if(*p) { + /* if there's anything more than a plain decimal number */ + *p++ = 0; + rc = sscanf(p, " - %6s", lrange); + } + else + rc = 0; + + err = str2unum(&config->localport, nextarg); + if(err || (config->localport > 65535)) return PARAM_BAD_USE; - if(rc == 1) + if(!rc) config->localportrange = 1; /* default number of ports to try */ else { + err = str2unum(&config->localportrange, lrange); + if(err || (config->localportrange > 65535)) + return PARAM_BAD_USE; config->localportrange -= config->localport; - if(config->localportrange < 1) { - warnf(global, "bad range input\n"); + if(config->localportrange < 1) return PARAM_BAD_USE; - } } break; + } case 'u': /* --ftp-alternative-to-user */ GetStr(&config->ftp_alternative_to_user, nextarg); break; diff --git a/src/tool_operate.c b/src/tool_operate.c index 5a72b6a8c..46ca316f9 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1371,9 +1371,8 @@ static CURLcode operate_do(struct GlobalConfig *global, /* curl 7.15.2 */ if(config->localport) { - my_setopt(curl, CURLOPT_LOCALPORT, (long)config->localport); - my_setopt_str(curl, CURLOPT_LOCALPORTRANGE, - (long)config->localportrange); + my_setopt(curl, CURLOPT_LOCALPORT, config->localport); + my_setopt_str(curl, CURLOPT_LOCALPORTRANGE, config->localportrange); } /* curl 7.15.5 */ |