[PATCH 6 of 6] Disabled redefinition of variables with v->set_handler

Maxim Dounin mdounin at mdounin.ru
Wed Jun 3 15:46:54 UTC 2026


# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1780500654 -10800
#      Wed Jun 03 18:30:54 2026 +0300
# Node ID 2425956404250ba696b066cab707b797813cef65
# Parent  8baa7a14576b2c9d7b7ef8c649544a5e54b0c12b
Disabled redefinition of variables with v->set_handler.

Changeable variables can be updated by the "set" directive, and
to support this ngx_http_add_variable() does not generate an error
when a changeable variable is added again.

This, however, makes it possible to redefine variables to completely
different use, such as from a builtin variable to a map{}.  And this
in turn might cause unexpected issues, such as when a variable with
set_handler is redefined to a map, which changes v->get_handler and
v->data, but not v->set_handler.  Most notably, this caused segmentation
faults when trying to define a map to the $limit_rate variable before
7504:c19ca381b2e6 (https://trac.nginx.org/nginx/ticket/1238).

With this change, redefinition of variables with v->set_handler is not
allowed unless the NGX_HTTP_VAR_WEAK flag is also provided, which is
currently used by "set" and other similar directives.

Note that this change changes the meaning of the NGX_HTTP_VAR_WEAK flag.
Previously, it was used solely to preserve get handler from prefix
variables.  Now the meaning of the flag becomes somewhat broader, and
now it means that we are defining a fallback variable to be used in "set"
or similar directives, and the caller is not going to redefine the
variable if it's already present.

Similar changes were made in the stream module.

diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -448,6 +448,12 @@ ngx_http_add_variable(ngx_conf_t *cf, ng
             return NULL;
         }
 
+        if (!(flags & NGX_HTTP_VAR_WEAK) && v->set_handler) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "the duplicate \"%V\" variable", name);
+            return NULL;
+        }
+
         if (!(flags & NGX_HTTP_VAR_WEAK)) {
             v->flags &= ~NGX_HTTP_VAR_WEAK;
         }
diff --git a/src/stream/ngx_stream_variables.c b/src/stream/ngx_stream_variables.c
--- a/src/stream/ngx_stream_variables.c
+++ b/src/stream/ngx_stream_variables.c
@@ -177,6 +177,12 @@ ngx_stream_add_variable(ngx_conf_t *cf, 
             return NULL;
         }
 
+        if (!(flags & NGX_STREAM_VAR_WEAK) && v->set_handler) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "the duplicate \"%V\" variable", name);
+            return NULL;
+        }
+
         if (!(flags & NGX_STREAM_VAR_WEAK)) {
             v->flags &= ~NGX_STREAM_VAR_WEAK;
         }



More information about the nginx-devel mailing list