]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Don't modify argv[] in user tools
authorDeHackEd <DeHackEd@users.noreply.github.com>
Mon, 20 Aug 2018 16:55:18 +0000 (12:55 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 20 Aug 2018 16:55:18 +0000 (09:55 -0700)
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

cmd/zfs/zfs_main.c
cmd/zpool/zpool_main.c

index 162cef6fba26f8028a74c957a1cb73667419f128..cf2d8f2d515e974442ad31dad90bfd101e31668d 100644 (file)
@@ -7910,6 +7910,7 @@ main(int argc, char **argv)
        int ret = 0;
        int i = 0;
        char *cmdname;
+       char **newargv;
 
        (void) setlocale(LC_ALL, "");
        (void) textdomain(TEXT_DOMAIN);
@@ -7962,17 +7963,26 @@ main(int argc, char **argv)
 
        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.
         */
        libzfs_mnttab_cache(g_zfs, B_TRUE);
        if (find_command_idx(cmdname, &i) == 0) {
                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) {
                verify(find_command_idx("set", &i) == 0);
                current_command = &command_table[i];
-               ret = command_table[i].func(argc, argv);
+               ret = command_table[i].func(argc, newargv);
        } else {
                (void) fprintf(stderr, gettext("unrecognized "
                    "command '%s'\n"), cmdname);
@@ -7980,6 +7990,10 @@ main(int argc, char **argv)
                ret = 1;
        }
 
+       for (i = 0; i < argc; i++)
+               free(newargv[i]);
+       free(newargv);
+
        if (ret == 0 && log_history)
                (void) zpool_log_history(g_zfs, history_str);
 
index 71943f2c0f80e27260f2116d76b161c7f8303618..73744a87c21e22807e69a9ffdf3408fa02392c6e 100644 (file)
@@ -8479,6 +8479,7 @@ main(int argc, char **argv)
        int ret = 0;
        int i = 0;
        char *cmdname;
+       char **newargv;
 
        (void) setlocale(LC_ALL, "");
        (void) textdomain(TEXT_DOMAIN);
@@ -8511,16 +8512,25 @@ main(int argc, char **argv)
 
        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.
         */
        if (find_command_idx(cmdname, &i) == 0) {
                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, '=')) {
                verify(find_command_idx("set", &i) == 0);
                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) {
                /*
                 * 'freeze' is a vile debugging abomination, so we treat
@@ -8544,6 +8554,10 @@ main(int argc, char **argv)
                ret = 1;
        }
 
+       for (i = 0; i < argc; i++)
+               free(newargv[i]);
+       free(newargv);
+
        if (ret == 0 && log_history)
                (void) zpool_log_history(g_zfs, history_str);