diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-08 23:26:16 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-08 23:26:16 +0200 |
commit | 19afe848eca8d3baf149cd7ed715489403360287 (patch) | |
tree | af410f580b86bcb37b463828e3bc60c03a855df6 | |
parent | 7b48eb4372c0b639bcb1eaedd63795c2dc0d9820 (diff) | |
download | busybox-w32-19afe848eca8d3baf149cd7ed715489403360287.tar.gz busybox-w32-19afe848eca8d3baf149cd7ed715489403360287.tar.bz2 busybox-w32-19afe848eca8d3baf149cd7ed715489403360287.zip |
ifplugd: replace potentially-leaking setenv with malloc/putenv/free
text data bss dec hex filename
842657 453 6828 849938 cf812 busybox_old
842722 453 6828 850003 cf853 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/ifplugd.c | 103 |
1 files changed, 20 insertions, 83 deletions
diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 41b04c4ed..01a7a49e5 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c | |||
@@ -93,6 +93,7 @@ enum { // constant fds | |||
93 | 93 | ||
94 | struct globals { | 94 | struct globals { |
95 | smallint iface_last_status; | 95 | smallint iface_last_status; |
96 | smallint iface_prev_status; | ||
96 | smallint iface_exists; | 97 | smallint iface_exists; |
97 | 98 | ||
98 | /* Used in getopt32, must have sizeof == sizeof(int) */ | 99 | /* Used in getopt32, must have sizeof == sizeof(int) */ |
@@ -121,97 +122,42 @@ struct globals { | |||
121 | } while (0) | 122 | } while (0) |
122 | 123 | ||
123 | 124 | ||
125 | static const char *strstatus(int status) | ||
126 | { | ||
127 | if (status == IFSTATUS_ERR) | ||
128 | return "error"; | ||
129 | return "down\0up" + (status * 5); | ||
130 | } | ||
131 | |||
124 | static int run_script(const char *action) | 132 | static int run_script(const char *action) |
125 | { | 133 | { |
134 | char *env_PREVIOUS, *env_CURRENT; | ||
126 | char *argv[5]; | 135 | char *argv[5]; |
127 | int r; | 136 | int r; |
128 | 137 | ||
129 | bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action); | 138 | bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action); |
130 | 139 | ||
131 | #if 1 | ||
132 | |||
133 | argv[0] = (char*) G.script_name; | 140 | argv[0] = (char*) G.script_name; |
134 | argv[1] = (char*) G.iface; | 141 | argv[1] = (char*) G.iface; |
135 | argv[2] = (char*) action; | 142 | argv[2] = (char*) action; |
136 | argv[3] = (char*) G.extra_arg; | 143 | argv[3] = (char*) G.extra_arg; |
137 | argv[4] = NULL; | 144 | argv[4] = NULL; |
138 | 145 | ||
146 | env_PREVIOUS = xasprintf("%s=%s", IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_prev_status)); | ||
147 | putenv(env_PREVIOUS); | ||
148 | env_CURRENT = xasprintf("%s=%s", IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_last_status)); | ||
149 | putenv(env_CURRENT); | ||
150 | |||
139 | /* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */ | 151 | /* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */ |
140 | r = spawn_and_wait(argv); | 152 | r = spawn_and_wait(argv); |
141 | 153 | ||
154 | unsetenv(IFPLUGD_ENV_PREVIOUS); | ||
155 | unsetenv(IFPLUGD_ENV_CURRENT); | ||
156 | free(env_PREVIOUS); | ||
157 | free(env_CURRENT); | ||
158 | |||
142 | bb_error_msg("exit code: %d", r & 0xff); | 159 | bb_error_msg("exit code: %d", r & 0xff); |
143 | return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r; | 160 | return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r; |
144 | |||
145 | #else /* insanity */ | ||
146 | |||
147 | struct fd_pair pipe_pair; | ||
148 | char buf[256]; | ||
149 | int i = 0; | ||
150 | |||
151 | xpiped_pair(pipe_pair); | ||
152 | |||
153 | pid = vfork(); | ||
154 | if (pid < 0) { | ||
155 | bb_perror_msg("fork"); | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | /* child */ | ||
160 | if (pid == 0) { | ||
161 | xmove_fd(pipe_pair.wr, 1); | ||
162 | xdup2(1, 2); | ||
163 | if (pipe_pair.rd > 2) | ||
164 | close(pipe_pair.rd); | ||
165 | |||
166 | // umask(0022); // Set up a sane umask | ||
167 | |||
168 | execlp(G.script_name, G.script_name, G.iface, action, G.extra_arg, NULL); | ||
169 | _exit(EXIT_FAILURE); | ||
170 | } | ||
171 | |||
172 | /* parent */ | ||
173 | close(pipe_pair.wr); | ||
174 | |||
175 | while (1) { | ||
176 | if (bb_got_signal && bb_got_signal != SIGCHLD) { | ||
177 | bb_error_msg("killing child"); | ||
178 | kill(pid, SIGTERM); | ||
179 | bb_got_signal = 0; | ||
180 | break; | ||
181 | } | ||
182 | |||
183 | r = read(pipe_pair.rd, &buf[i], 1); | ||
184 | |||
185 | if (buf[i] == '\n' || i == sizeof(buf)-2 || r != 1) { | ||
186 | if (r == 1 && buf[i] != '\n') | ||
187 | i++; | ||
188 | |||
189 | buf[i] = '\0'; | ||
190 | |||
191 | if (i > 0) | ||
192 | bb_error_msg("client: %s", buf); | ||
193 | |||
194 | i = 0; | ||
195 | } else { | ||
196 | i++; | ||
197 | } | ||
198 | |||
199 | if (r != 1) | ||
200 | break; | ||
201 | } | ||
202 | |||
203 | close(pipe_pair.rd); | ||
204 | |||
205 | wait(&r); | ||
206 | |||
207 | if (!WIFEXITED(r) || WEXITSTATUS(r) != 0) { | ||
208 | bb_error_msg("program execution failed, return value is %i", | ||
209 | WEXITSTATUS(r)); | ||
210 | return option_mask32 & FLAG_IGNORE_RETVAL ? 0 : WEXITSTATUS(r); | ||
211 | } | ||
212 | bb_error_msg("program executed successfully"); | ||
213 | return 0; | ||
214 | #endif | ||
215 | } | 161 | } |
216 | 162 | ||
217 | static int network_ioctl(int request, void* data, const char *errmsg) | 163 | static int network_ioctl(int request, void* data, const char *errmsg) |
@@ -228,13 +174,6 @@ static void set_ifreq_to_ifname(struct ifreq *ifreq) | |||
228 | strncpy_IFNAMSIZ(ifreq->ifr_name, G.iface); | 174 | strncpy_IFNAMSIZ(ifreq->ifr_name, G.iface); |
229 | } | 175 | } |
230 | 176 | ||
231 | static const char *strstatus(int status) | ||
232 | { | ||
233 | if (status == IFSTATUS_ERR) | ||
234 | return "error"; | ||
235 | return "down\0up" + (status * 5); | ||
236 | } | ||
237 | |||
238 | static void up_iface(void) | 177 | static void up_iface(void) |
239 | { | 178 | { |
240 | struct ifreq ifrequest; | 179 | struct ifreq ifrequest; |
@@ -474,9 +413,7 @@ static smallint detect_link(void) | |||
474 | } | 413 | } |
475 | 414 | ||
476 | if (status != G.iface_last_status) { | 415 | if (status != G.iface_last_status) { |
477 | //TODO: is it safe to repeatedly do this? | 416 | G.iface_prev_status = G.iface_last_status; |
478 | setenv(IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_last_status), 1); | ||
479 | setenv(IFPLUGD_ENV_CURRENT, strstatus(status), 1); | ||
480 | G.iface_last_status = status; | 417 | G.iface_last_status = status; |
481 | } | 418 | } |
482 | 419 | ||