Skip to content

Commit

Permalink
tool_getparam: repair cleanarg
Browse files Browse the repository at this point in the history
Regression since 9e5669f.

Make sure the "cleaning" of command line arguments is done on the
original argv[] pointers. As a bonus, it also exits better on out of
memory error.

Reported-by: Litter White
Fixes #9128
Closes #9130
  • Loading branch information
bagder committed Jul 10, 2022
1 parent eab2589 commit bf7e887
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 38 deletions.
61 changes: 42 additions & 19 deletions src/tool_getparam.c
Expand Up @@ -487,7 +487,6 @@ GetFileAndPassword(char *nextarg, char **file, char **password)
Curl_safefree(*password);
*password = passphrase;
}
cleanarg(nextarg);
}

/* Get a size parameter for '--limit-rate' or '--max-filesize'.
Expand Down Expand Up @@ -542,8 +541,24 @@ static ParameterError GetSizeParameter(struct GlobalConfig *global,
return PARAM_OK;
}

static void cleanarg(char *str)
{
#ifdef HAVE_WRITABLE_ARGV
/* now that GetStr has copied the contents of nextarg, wipe the next
* argument out so that the username:password isn't displayed in the
* system process list */
if(str) {
size_t len = strlen(str);
memset(str, ' ', len);
}
#else
(void)str;
#endif
}

ParameterError getparameter(const char *flag, /* f or -long-flag */
char *nextarg, /* NULL if unset */
char *clearthis,
bool *usedarg, /* set to TRUE if the arg
has been used */
struct GlobalConfig *global,
Expand Down Expand Up @@ -675,7 +690,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;
case 'B': /* OAuth 2.0 bearer token */
GetStr(&config->oauth_bearer, nextarg);
cleanarg(nextarg);
cleanarg(clearthis);
config->authtype |= CURLAUTH_BEARER;
break;
case 'c': /* connect-timeout */
Expand Down Expand Up @@ -1637,6 +1652,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
case 'E':
switch(subletter) {
case '\0': /* certificate file */
cleanarg(clearthis);
GetFileAndPassword(nextarg, &config->cert, &config->key_passwd);
break;
case 'a': /* CA info PEM file */
Expand All @@ -1653,7 +1669,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;
case 'e': /* private key passphrase */
GetStr(&config->key_passwd, nextarg);
cleanarg(nextarg);
cleanarg(clearthis);
break;
case 'f': /* crypto engine */
GetStr(&config->engine, nextarg);
Expand All @@ -1679,19 +1695,19 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;
case 'k': /* TLS username */
if(!(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)) {
cleanarg(nextarg);
cleanarg(clearthis);
return PARAM_LIBCURL_DOESNT_SUPPORT;
}
GetStr(&config->tls_username, nextarg);
cleanarg(nextarg);
cleanarg(clearthis);
break;
case 'l': /* TLS password */
if(!(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)) {
cleanarg(nextarg);
cleanarg(clearthis);
return PARAM_LIBCURL_DOESNT_SUPPORT;
}
GetStr(&config->tls_password, nextarg);
cleanarg(nextarg);
cleanarg(clearthis);
break;
case 'm': /* TLS authentication type */
if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
Expand Down Expand Up @@ -1752,21 +1768,19 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;

case 'u': /* TLS username for proxy */
cleanarg(clearthis);
if(!(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)) {
cleanarg(nextarg);
return PARAM_LIBCURL_DOESNT_SUPPORT;
}
GetStr(&config->proxy_tls_username, nextarg);
cleanarg(nextarg);
break;

case 'v': /* TLS password for proxy */
cleanarg(clearthis);
if(!(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)) {
cleanarg(nextarg);
return PARAM_LIBCURL_DOESNT_SUPPORT;
}
GetStr(&config->proxy_tls_password, nextarg);
cleanarg(nextarg);
break;

case 'w': /* TLS authentication type for proxy */
Expand All @@ -1780,6 +1794,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
break;

case 'x': /* certificate file for proxy */
cleanarg(clearthis);
GetFileAndPassword(nextarg, &config->proxy_cert,
&config->proxy_key_passwd);
break;
Expand All @@ -1798,7 +1813,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */

case '1': /* private key passphrase for proxy */
GetStr(&config->proxy_key_passwd, nextarg);
cleanarg(nextarg);
cleanarg(clearthis);
break;

case '2': /* ciphers for proxy */
Expand Down Expand Up @@ -2246,12 +2261,12 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
case 'u':
/* user:password */
GetStr(&config->userpwd, nextarg);
cleanarg(nextarg);
cleanarg(clearthis);
break;
case 'U':
/* Proxy user:password */
GetStr(&config->proxyuserpwd, nextarg);
cleanarg(nextarg);
cleanarg(clearthis);
break;
case 'v':
if(toggle) {
Expand Down Expand Up @@ -2424,11 +2439,19 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
following (URL) argument to start with -. */
stillflags = FALSE;
else {
char *nextarg = (i < (argc - 1))
? curlx_convert_tchar_to_UTF8(argv[i + 1])
: NULL;
char *nextarg = NULL;
char *clear = NULL;
if(i < (argc - 1)) {
nextarg = curlx_convert_tchar_to_UTF8(argv[i + 1]);
if(!nextarg) {
curlx_unicodefree(orig_opt);
return PARAM_NO_MEM;
}
clear = argv[i + 1];
}

result = getparameter(orig_opt, nextarg, &passarg, global, config);
result = getparameter(orig_opt, nextarg, clear, &passarg,
global, config);

curlx_unicodefree(nextarg);
config = global->last;
Expand Down Expand Up @@ -2466,7 +2489,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
bool used;

/* Just add the URL please */
result = getparameter("--url", orig_opt, &used, global,
result = getparameter("--url", orig_opt, NULL, &used, global,
config);
}

Expand Down
3 changes: 2 additions & 1 deletion src/tool_getparam.h
Expand Up @@ -54,7 +54,8 @@ typedef enum {
struct GlobalConfig;
struct OperationConfig;

ParameterError getparameter(const char *flag, char *nextarg, bool *usedarg,
ParameterError getparameter(const char *flag, char *nextarg, char *clearthis,
bool *usedarg,
struct GlobalConfig *global,
struct OperationConfig *operation);

Expand Down
15 changes: 0 additions & 15 deletions src/tool_paramhlp.c
Expand Up @@ -116,21 +116,6 @@ ParameterError file2memory(char **bufp, size_t *size, FILE *file)
return PARAM_OK;
}

void cleanarg(char *str)
{
#ifdef HAVE_WRITABLE_ARGV
/* now that GetStr has copied the contents of nextarg, wipe the next
* argument out so that the username:password isn't displayed in the
* system process list */
if(str) {
size_t len = strlen(str);
memset(str, ' ', len);
}
#else
(void)str;
#endif
}

/*
* Parse the string and write the long in the given address. Return PARAM_OK
* on success, otherwise a parameter specific error enum.
Expand Down
2 changes: 0 additions & 2 deletions src/tool_paramhlp.h
Expand Up @@ -31,8 +31,6 @@ ParameterError file2string(char **bufp, FILE *file);

ParameterError file2memory(char **bufp, size_t *size, FILE *file);

void cleanarg(char *str);

ParameterError str2num(long *val, const char *str);
ParameterError str2unum(long *val, const char *str);
ParameterError oct2nummax(long *val, const char *str, long max);
Expand Down
2 changes: 1 addition & 1 deletion src/tool_parsecfg.c
Expand Up @@ -223,7 +223,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global)
#ifdef DEBUG_CONFIG
fprintf(stderr, "PARAM: \"%s\"\n",(param ? param : "(null)"));
#endif
res = getparameter(option, param, &usedarg, global, operation);
res = getparameter(option, param, NULL, &usedarg, global, operation);
operation = global->last;

if(!res && param && *param && !usedarg)
Expand Down

0 comments on commit bf7e887

Please sign in to comment.