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
This commit is contained in:
Daniel Stenberg 2018-11-05 11:57:29 +01:00
parent bda4ef417a
commit 52db54869e
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 27 additions and 15 deletions

View File

@ -69,8 +69,8 @@ struct OperationConfig {
char *headerfile; char *headerfile;
char *ftpport; char *ftpport;
char *iface; char *iface;
int localport; long localport;
int localportrange; long localportrange;
unsigned short porttouse; unsigned short porttouse;
char *range; char *range;
long low_speed_limit; long low_speed_limit;

View File

@ -935,22 +935,35 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
case 'r': /* --ftp-method (undocumented at this point) */ case 'r': /* --ftp-method (undocumented at this point) */
config->ftp_filemethod = ftpfilemethod(config, nextarg); config->ftp_filemethod = ftpfilemethod(config, nextarg);
break; break;
case 's': /* --local-port */ case 's': { /* --local-port */
rc = sscanf(nextarg, "%d - %d", char lrange[7]; /* 16bit base 10 is 5 digits, but we allow 6 so that
&config->localport, this catches overflows, not just truncates */
&config->localportrange); char *p = nextarg;
if(!rc) 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; return PARAM_BAD_USE;
if(rc == 1) if(!rc)
config->localportrange = 1; /* default number of ports to try */ config->localportrange = 1; /* default number of ports to try */
else { else {
config->localportrange -= config->localport; err = str2unum(&config->localportrange, lrange);
if(config->localportrange < 1) { if(err || (config->localportrange > 65535))
warnf(global, "bad range input\n"); return PARAM_BAD_USE;
config->localportrange -= config->localport;
if(config->localportrange < 1)
return PARAM_BAD_USE; return PARAM_BAD_USE;
}
} }
break; break;
}
case 'u': /* --ftp-alternative-to-user */ case 'u': /* --ftp-alternative-to-user */
GetStr(&config->ftp_alternative_to_user, nextarg); GetStr(&config->ftp_alternative_to_user, nextarg);
break; break;

View File

@ -1371,9 +1371,8 @@ static CURLcode operate_do(struct GlobalConfig *global,
/* curl 7.15.2 */ /* curl 7.15.2 */
if(config->localport) { if(config->localport) {
my_setopt(curl, CURLOPT_LOCALPORT, (long)config->localport); my_setopt(curl, CURLOPT_LOCALPORT, config->localport);
my_setopt_str(curl, CURLOPT_LOCALPORTRANGE, my_setopt_str(curl, CURLOPT_LOCALPORTRANGE, config->localportrange);
(long)config->localportrange);
} }
/* curl 7.15.5 */ /* curl 7.15.5 */