aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-22 03:04:20 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-22 03:04:20 +0200
commite4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748 (patch)
tree7d0279df538daa9f4df7be4044cae4a2ffdfe023
parentbbf17bbf326c7157ca237b9659472ddf7626e68d (diff)
downloadbusybox-w32-e4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748.tar.gz
busybox-w32-e4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748.tar.bz2
busybox-w32-e4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748.zip
zcip: fix slow environment leak
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h3
-rw-r--r--networking/ifplugd.c6
-rw-r--r--networking/zcip.c9
3 files changed, 12 insertions, 6 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 0317c7d6a..6abf88218 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1485,6 +1485,9 @@ extern void selinux_or_die(void) FAST_FUNC;
1485 * HOME=pw->pw_dir 1485 * HOME=pw->pw_dir
1486 * SHELL=shell 1486 * SHELL=shell
1487 * else does nothing 1487 * else does nothing
1488 *
1489 * NB: CHANGEENV and CLEARENV use setenv() - this leaks memory!
1490 * If setup_environment() is used is vforked child, this leaks memory _in parent too_!
1488 */ 1491 */
1489#define SETUP_ENV_CHANGEENV (1 << 0) 1492#define SETUP_ENV_CHANGEENV (1 << 0)
1490#define SETUP_ENV_CLEARENV (1 << 1) 1493#define SETUP_ENV_CLEARENV (1 << 1)
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index c36bc9524..9bc1a075f 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -342,10 +342,8 @@ static int run_script(const char *action)
342 /* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */ 342 /* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */
343 r = spawn_and_wait(argv); 343 r = spawn_and_wait(argv);
344 344
345 unsetenv(IFPLUGD_ENV_PREVIOUS); 345 bb_unsetenv_and_free(env_PREVIOUS);
346 unsetenv(IFPLUGD_ENV_CURRENT); 346 bb_unsetenv_and_free(env_CURRENT);
347 free(env_PREVIOUS);
348 free(env_CURRENT);
349 347
350 bb_error_msg("exit code: %d", r & 0xff); 348 bb_error_msg("exit code: %d", r & 0xff);
351 return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r; 349 return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r;
diff --git a/networking/zcip.c b/networking/zcip.c
index 232165efa..94174a165 100644
--- a/networking/zcip.c
+++ b/networking/zcip.c
@@ -183,6 +183,7 @@ static int run(char *argv[3], const char *param, uint32_t nip)
183 int status; 183 int status;
184 const char *addr = addr; /* for gcc */ 184 const char *addr = addr; /* for gcc */
185 const char *fmt = "%s %s %s" + 3; 185 const char *fmt = "%s %s %s" + 3;
186 char *env_ip = env_ip;
186 187
187 argv[2] = (char*)param; 188 argv[2] = (char*)param;
188 189
@@ -190,12 +191,16 @@ static int run(char *argv[3], const char *param, uint32_t nip)
190 191
191 if (nip != 0) { 192 if (nip != 0) {
192 addr = nip_to_a(nip); 193 addr = nip_to_a(nip);
193 xsetenv("ip", addr); 194 /* Must not use setenv() repeatedly, it leaks memory. Use putenv() */
195 env_ip = xasprintf("ip=%s", addr);
196 putenv(env_ip);
194 fmt -= 3; 197 fmt -= 3;
195 } 198 }
196 bb_error_msg(fmt, argv[2], argv[0], addr); 199 bb_error_msg(fmt, argv[2], argv[0], addr);
197
198 status = spawn_and_wait(argv + 1); 200 status = spawn_and_wait(argv + 1);
201 if (nip != 0)
202 bb_unsetenv_and_free(env_ip);
203
199 if (status < 0) { 204 if (status < 0) {
200 bb_perror_msg("%s %s %s" + 3, argv[2], argv[0]); 205 bb_perror_msg("%s %s %s" + 3, argv[2], argv[0]);
201 return -errno; 206 return -errno;