changeset 9134:c209dc4eed17

Core: fixed environment variables on exit. Similarly to 6822:c045b4926b2c, environment variables introduced with the "env" directive (and "NGINX_BPF_MAPS" added by QUIC) are now allocated via ngx_alloc(), and explicitly freed by a cleanup handler if no longer used. In collaboration with Sergey Kandaurov.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 19 Jul 2023 05:09:23 +0300
parents f91dc350be9f
children 904c99bede17
files src/core/nginx.c
diffstat 1 files changed, 51 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -13,6 +13,7 @@
 static void ngx_show_version_info(void);
 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
 static void ngx_cleanup_environment(void *data);
+static void ngx_cleanup_environment_variable(void *data);
 static ngx_int_t ngx_get_options(int argc, char *const *argv);
 static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
 static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
@@ -518,7 +519,8 @@ ngx_add_inherited_sockets(ngx_cycle_t *c
 char **
 ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
 {
-    char                **p, **env;
+    char                **p, **env, *str;
+    size_t                len;
     ngx_str_t            *var;
     ngx_uint_t            i, n;
     ngx_core_conf_t      *ccf;
@@ -600,7 +602,31 @@ tz_found:
     for (i = 0; i < ccf->env.nelts; i++) {
 
         if (var[i].data[var[i].len] == '=') {
-            env[n++] = (char *) var[i].data;
+
+            if (last) {
+                env[n++] = (char *) var[i].data;
+                continue;
+            }
+
+            cln = ngx_pool_cleanup_add(cycle->pool, 0);
+            if (cln == NULL) {
+                return NULL;
+            }
+
+            len = ngx_strlen(var[i].data) + 1;
+
+            str = ngx_alloc(len, cycle->log);
+            if (str == NULL) {
+                return NULL;
+            }
+
+            ngx_memcpy(str, var[i].data, len);
+
+            cln->handler = ngx_cleanup_environment_variable;
+            cln->data = str;
+
+            env[n++] = str;
+
             continue;
         }
 
@@ -645,6 +671,29 @@ ngx_cleanup_environment(void *data)
 }
 
 
+static void
+ngx_cleanup_environment_variable(void *data)
+{
+    char  *var = data;
+
+    char  **p;
+
+    for (p = environ; *p; p++) {
+
+        /*
+         * if an environment variable is still used, as it happens on exit,
+         * the only option is to leak it
+         */
+
+        if (*p == var) {
+            return;
+        }
+    }
+
+    ngx_free(var);
+}
+
+
 ngx_pid_t
 ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
 {