]>
Commit | Line | Data |
---|---|---|
a010b409 SI |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: DeHackEd <DeHackEd@users.noreply.github.com> | |
3 | Date: Mon, 20 Aug 2018 12:55:18 -0400 | |
4 | Subject: [PATCH] Don't modify argv[] in user tools | |
5 | ||
6 | argv[] gets modified during string parsing for input arguments. This | |
7 | is reflected in the live process listing. Don't do that. | |
8 | ||
9 | Reviewed-by: Serapheim Dimitropoulos <serapheim@delphix.com> | |
10 | Reviewed-by: loli10K <ezomori.nozomu@gmail.com> | |
11 | Reviewed-by: Giuseppe Di Natale <guss80@gmail.com> | |
12 | Reviewed-by: George Melikov <mail@gmelikov.ru> | |
13 | Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> | |
14 | Signed-off-by: DHE <git@dehacked.net> | |
15 | Closes #7760 | |
16 | ||
17 | Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> | |
18 | --- | |
19 | cmd/zfs/zfs_main.c | 18 ++++++++++++++++-- | |
20 | cmd/zpool/zpool_main.c | 18 ++++++++++++++++-- | |
21 | 2 files changed, 32 insertions(+), 4 deletions(-) | |
22 | ||
23 | diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c | |
24 | index f57df858..275d9c89 100644 | |
25 | --- a/cmd/zfs/zfs_main.c | |
26 | +++ b/cmd/zfs/zfs_main.c | |
27 | @@ -7041,6 +7041,7 @@ main(int argc, char **argv) | |
28 | int ret = 0; | |
29 | int i = 0; | |
30 | char *cmdname; | |
31 | + char **newargv; | |
32 | ||
33 | (void) setlocale(LC_ALL, ""); | |
34 | (void) textdomain(TEXT_DOMAIN); | |
35 | @@ -7096,16 +7097,25 @@ main(int argc, char **argv) | |
36 | libzfs_print_on_error(g_zfs, B_TRUE); | |
37 | ||
38 | /* | |
39 | + * Many commands modify input strings for string parsing reasons. | |
40 | + * We create a copy to protect the original argv. | |
41 | + */ | |
42 | + newargv = malloc((argc + 1) * sizeof (newargv[0])); | |
43 | + for (i = 0; i < argc; i++) | |
44 | + newargv[i] = strdup(argv[i]); | |
45 | + newargv[argc] = NULL; | |
46 | + | |
47 | + /* | |
48 | * Run the appropriate command. | |
49 | */ | |
50 | libzfs_mnttab_cache(g_zfs, B_TRUE); | |
51 | if (find_command_idx(cmdname, &i) == 0) { | |
52 | current_command = &command_table[i]; | |
53 | - ret = command_table[i].func(argc - 1, argv + 1); | |
54 | + ret = command_table[i].func(argc - 1, newargv + 1); | |
55 | } else if (strchr(cmdname, '=') != NULL) { | |
56 | verify(find_command_idx("set", &i) == 0); | |
57 | current_command = &command_table[i]; | |
58 | - ret = command_table[i].func(argc, argv); | |
59 | + ret = command_table[i].func(argc, newargv); | |
60 | } else { | |
61 | (void) fprintf(stderr, gettext("unrecognized " | |
62 | "command '%s'\n"), cmdname); | |
63 | @@ -7113,6 +7123,10 @@ main(int argc, char **argv) | |
64 | ret = 1; | |
65 | } | |
66 | ||
67 | + for (i = 0; i < argc; i++) | |
68 | + free(newargv[i]); | |
69 | + free(newargv); | |
70 | + | |
71 | if (ret == 0 && log_history) | |
72 | (void) zpool_log_history(g_zfs, history_str); | |
73 | ||
74 | diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c | |
75 | index 97697011..a4fd0321 100644 | |
76 | --- a/cmd/zpool/zpool_main.c | |
77 | +++ b/cmd/zpool/zpool_main.c | |
78 | @@ -7971,6 +7971,7 @@ main(int argc, char **argv) | |
79 | int ret = 0; | |
80 | int i = 0; | |
81 | char *cmdname; | |
82 | + char **newargv; | |
83 | ||
84 | (void) setlocale(LC_ALL, ""); | |
85 | (void) textdomain(TEXT_DOMAIN); | |
86 | @@ -8006,15 +8007,24 @@ main(int argc, char **argv) | |
87 | zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); | |
88 | ||
89 | /* | |
90 | + * Many commands modify input strings for string parsing reasons. | |
91 | + * We create a copy to protect the original argv. | |
92 | + */ | |
93 | + newargv = malloc((argc + 1) * sizeof (newargv[0])); | |
94 | + for (i = 0; i < argc; i++) | |
95 | + newargv[i] = strdup(argv[i]); | |
96 | + newargv[argc] = NULL; | |
97 | + | |
98 | + /* | |
99 | * Run the appropriate command. | |
100 | */ | |
101 | if (find_command_idx(cmdname, &i) == 0) { | |
102 | current_command = &command_table[i]; | |
103 | - ret = command_table[i].func(argc - 1, argv + 1); | |
104 | + ret = command_table[i].func(argc - 1, newargv + 1); | |
105 | } else if (strchr(cmdname, '=')) { | |
106 | verify(find_command_idx("set", &i) == 0); | |
107 | current_command = &command_table[i]; | |
108 | - ret = command_table[i].func(argc, argv); | |
109 | + ret = command_table[i].func(argc, newargv); | |
110 | } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { | |
111 | /* | |
112 | * 'freeze' is a vile debugging abomination, so we treat | |
113 | @@ -8031,6 +8041,10 @@ main(int argc, char **argv) | |
114 | ret = 1; | |
115 | } | |
116 | ||
117 | + for (i = 0; i < argc; i++) | |
118 | + free(newargv[i]); | |
119 | + free(newargv); | |
120 | + | |
121 | if (ret == 0 && log_history) | |
122 | (void) zpool_log_history(g_zfs, history_str); | |
123 |