zcip: fix slow environment leak
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 22 Jul 2017 01:04:20 +0000 (03:04 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 22 Jul 2017 01:04:20 +0000 (03:04 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/libbb.h
networking/ifplugd.c
networking/zcip.c

index 0317c7d6ae662431b0e18a4ee9c16e0e694499a4..6abf88218de88e0d44f4ae5a2b8c0f7bc0da51d2 100644 (file)
@@ -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)
index c36bc952429b79aef7e37b50825b1b0b0a4e0827..9bc1a075f51bcfeb201ddc4e29a791252e4d622f 100644 (file)
@@ -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;
index 232165efa9825926d4a949b22c10cad8c554f336..94174a165680f8eb24d06dba3ec0eef018655024 100644 (file)
@@ -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;