[git commit] zcip: fix slow environment leak

Denys Vlasenko vda.linux at googlemail.com
Sat Jul 22 01:04:20 UTC 2017


commit: https://git.busybox.net/busybox/commit/?id=e4f6bfd6fec87e8eb77f1a9fe34b8b7884ef9748
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 include/libbb.h      | 3 +++
 networking/ifplugd.c | 6 ++----
 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;


More information about the busybox-cvs mailing list