[nginx] Disabled redefinition of variables with v->set_handler.

Maxim Dounin mdounin at mdounin.ru
Mon Jun 8 14:56:05 UTC 2026


details:   http://freenginx.org/hg/nginx/rev/5930e96ebd5a
branches:  
changeset: 9555:5930e96ebd5a
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Mon Jun 08 17:54:20 2026 +0300
description:
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.

diffstat:

 src/http/ngx_http_variables.c     |  6 ++++++
 src/stream/ngx_stream_variables.c |  6 ++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diffs (32 lines):

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