Don't modify argv[] in user tools
argv[] gets modified during string parsing for input arguments. This is reflected in the live process listing. Don't do that. Reviewed-by: Serapheim Dimitropoulos <serapheim@delphix.com> Reviewed-by: loli10K <ezomori.nozomu@gmail.com> Reviewed-by: Giuseppe Di Natale <guss80@gmail.com> Reviewed-by: George Melikov <mail@gmelikov.ru> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: DHE <git@dehacked.net> Closes #7760
This commit is contained in:
parent
98bc8e0b23
commit
778290d5bc
|
@ -7041,6 +7041,7 @@ main(int argc, char **argv)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char *cmdname;
|
char *cmdname;
|
||||||
|
char **newargv;
|
||||||
|
|
||||||
(void) setlocale(LC_ALL, "");
|
(void) setlocale(LC_ALL, "");
|
||||||
(void) textdomain(TEXT_DOMAIN);
|
(void) textdomain(TEXT_DOMAIN);
|
||||||
|
@ -7095,17 +7096,26 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
libzfs_print_on_error(g_zfs, B_TRUE);
|
libzfs_print_on_error(g_zfs, B_TRUE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Many commands modify input strings for string parsing reasons.
|
||||||
|
* We create a copy to protect the original argv.
|
||||||
|
*/
|
||||||
|
newargv = malloc((argc + 1) * sizeof (newargv[0]));
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
newargv[i] = strdup(argv[i]);
|
||||||
|
newargv[argc] = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run the appropriate command.
|
* Run the appropriate command.
|
||||||
*/
|
*/
|
||||||
libzfs_mnttab_cache(g_zfs, B_TRUE);
|
libzfs_mnttab_cache(g_zfs, B_TRUE);
|
||||||
if (find_command_idx(cmdname, &i) == 0) {
|
if (find_command_idx(cmdname, &i) == 0) {
|
||||||
current_command = &command_table[i];
|
current_command = &command_table[i];
|
||||||
ret = command_table[i].func(argc - 1, argv + 1);
|
ret = command_table[i].func(argc - 1, newargv + 1);
|
||||||
} else if (strchr(cmdname, '=') != NULL) {
|
} else if (strchr(cmdname, '=') != NULL) {
|
||||||
verify(find_command_idx("set", &i) == 0);
|
verify(find_command_idx("set", &i) == 0);
|
||||||
current_command = &command_table[i];
|
current_command = &command_table[i];
|
||||||
ret = command_table[i].func(argc, argv);
|
ret = command_table[i].func(argc, newargv);
|
||||||
} else {
|
} else {
|
||||||
(void) fprintf(stderr, gettext("unrecognized "
|
(void) fprintf(stderr, gettext("unrecognized "
|
||||||
"command '%s'\n"), cmdname);
|
"command '%s'\n"), cmdname);
|
||||||
|
@ -7113,6 +7123,10 @@ main(int argc, char **argv)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
free(newargv[i]);
|
||||||
|
free(newargv);
|
||||||
|
|
||||||
if (ret == 0 && log_history)
|
if (ret == 0 && log_history)
|
||||||
(void) zpool_log_history(g_zfs, history_str);
|
(void) zpool_log_history(g_zfs, history_str);
|
||||||
|
|
||||||
|
|
|
@ -7971,6 +7971,7 @@ main(int argc, char **argv)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char *cmdname;
|
char *cmdname;
|
||||||
|
char **newargv;
|
||||||
|
|
||||||
(void) setlocale(LC_ALL, "");
|
(void) setlocale(LC_ALL, "");
|
||||||
(void) textdomain(TEXT_DOMAIN);
|
(void) textdomain(TEXT_DOMAIN);
|
||||||
|
@ -8005,16 +8006,25 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
|
zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Many commands modify input strings for string parsing reasons.
|
||||||
|
* We create a copy to protect the original argv.
|
||||||
|
*/
|
||||||
|
newargv = malloc((argc + 1) * sizeof (newargv[0]));
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
newargv[i] = strdup(argv[i]);
|
||||||
|
newargv[argc] = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run the appropriate command.
|
* Run the appropriate command.
|
||||||
*/
|
*/
|
||||||
if (find_command_idx(cmdname, &i) == 0) {
|
if (find_command_idx(cmdname, &i) == 0) {
|
||||||
current_command = &command_table[i];
|
current_command = &command_table[i];
|
||||||
ret = command_table[i].func(argc - 1, argv + 1);
|
ret = command_table[i].func(argc - 1, newargv + 1);
|
||||||
} else if (strchr(cmdname, '=')) {
|
} else if (strchr(cmdname, '=')) {
|
||||||
verify(find_command_idx("set", &i) == 0);
|
verify(find_command_idx("set", &i) == 0);
|
||||||
current_command = &command_table[i];
|
current_command = &command_table[i];
|
||||||
ret = command_table[i].func(argc, argv);
|
ret = command_table[i].func(argc, newargv);
|
||||||
} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
|
} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
|
||||||
/*
|
/*
|
||||||
* 'freeze' is a vile debugging abomination, so we treat
|
* 'freeze' is a vile debugging abomination, so we treat
|
||||||
|
@ -8031,6 +8041,10 @@ main(int argc, char **argv)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
free(newargv[i]);
|
||||||
|
free(newargv);
|
||||||
|
|
||||||
if (ret == 0 && log_history)
|
if (ret == 0 && log_history)
|
||||||
(void) zpool_log_history(g_zfs, history_str);
|
(void) zpool_log_history(g_zfs, history_str);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue