diff options
author | Denys Vlasenko | 2017-07-22 03:04:20 +0200 |
---|---|---|
committer | Denys Vlasenko | 2017-07-22 03:04:20 +0200 |
commit | e4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748 (patch) | |
tree | 7d0279df538daa9f4df7be4044cae4a2ffdfe023 | |
parent | bbf17bbf326c7157ca237b9659472ddf7626e68d (diff) | |
download | busybox-e4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748.zip busybox-e4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748.tar.gz |
zcip: fix slow environment leak
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/libbb.h | 3 | ||||
-rw-r--r-- | networking/ifplugd.c | 6 | ||||
-rw-r--r-- | networking/zcip.c | 9 |
3 files changed, 12 insertions, 6 deletions
diff --git a/include/libbb.h b/include/libbb.h index 0317c7d..6abf882 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1485,6 +1485,9 @@ extern void selinux_or_die(void) FAST_FUNC; * HOME=pw->pw_dir * SHELL=shell * else does nothing + * + * NB: CHANGEENV and CLEARENV use setenv() - this leaks memory! + * If setup_environment() is used is vforked child, this leaks memory _in parent too_! */ #define SETUP_ENV_CHANGEENV (1 << 0) #define SETUP_ENV_CLEARENV (1 << 1) diff --git a/networking/ifplugd.c b/networking/ifplugd.c index c36bc95..9bc1a07 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -342,10 +342,8 @@ static int run_script(const char *action) /* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */ r = spawn_and_wait(argv); - unsetenv(IFPLUGD_ENV_PREVIOUS); - unsetenv(IFPLUGD_ENV_CURRENT); - free(env_PREVIOUS); - free(env_CURRENT); + bb_unsetenv_and_free(env_PREVIOUS); + bb_unsetenv_and_free(env_CURRENT); bb_error_msg("exit code: %d", r & 0xff); return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r; diff --git a/networking/zcip.c b/networking/zcip.c index 232165e..94174a1 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) int status; const char *addr = addr; /* for gcc */ const char *fmt = "%s %s %s" + 3; + char *env_ip = env_ip; argv[2] = (char*)param; @@ -190,12 +191,16 @@ static int run(char *argv[3], const char *param, uint32_t nip) if (nip != 0) { addr = nip_to_a(nip); - xsetenv("ip", addr); + /* Must not use setenv() repeatedly, it leaks memory. Use putenv() */ + env_ip = xasprintf("ip=%s", addr); + putenv(env_ip); fmt -= 3; } bb_error_msg(fmt, argv[2], argv[0], addr); - status = spawn_and_wait(argv + 1); + if (nip != 0) + bb_unsetenv_and_free(env_ip); + if (status < 0) { bb_perror_msg("%s %s %s" + 3, argv[2], argv[0]); return -errno; |