Opened 10 years ago

Closed 10 years ago

#600 closed defect (fixed)

segfault in ngx_http_get_variable()

Reported by: Xiaochen Wang Owned by: Valentin V. Bartenev
Priority: minor Milestone:
Component: nginx-core Version:
Keywords: Cc:
uname -a: Linux *** 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.7.2
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-52)

Description (last modified by Maxim Dounin)

easy to reproduce:

  1. nginx configure:
            location / {
                set $sent_http_foo "bar";
                ssi on;
                root   html;
            }
    
  2. The content of html/index.html is '<!--#echo var="sent_http_foo" -->'
  3. Requesting uri /index.html will trigger the segfault

coredump backtrace:

(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x0000000000438555 in ngx_http_get_variable (r=0xbe87f0, name=<value optimized out>, key=<value optimized out>) at src/http/ngx_http_variables.c:565
#2  0x000000000044b50f in ngx_http_ssi_echo (r=0xbe87f0, ctx=0xbe9ab8, params=0x7fff6d998cb0) at src/http/modules/ngx_http_ssi_filter_module.c:2262
...
(gdb) frame 1
#1  0x0000000000438555 in ngx_http_get_variable (r=0xbe87f0, name=<value optimized out>,
    key=<value optimized out>) at src/http/ngx_http_variables.c:565
565                 if (vv && v->get_handler(r, vv, v->data) == NGX_OK) {
(gdb) print vv
$7 = (ngx_http_variable_value_t *) 0xbea000
(gdb) print v->get_handler
$8 = (ngx_http_get_variable_pt) 0                     <<< v->get_handler is NULL

Another module ngx.lua (https://github.com/openresty/lua-nginx-module), using ngx_http_get_variable() api, will trigger this segfault too.

See configure as following, requesting uri / will trigger the segfault.

        location / {
            set $http_foo "bar";
            content_by_lua "ngx.say(ngx.var.http_foo)";
        }

Change History (6)

comment:1 by Valentin V. Bartenev, 10 years ago

Owner: set to Valentin V. Bartenev
Status: newassigned

This looks like a valid problem. Thanks.

comment:2 by Maxim Dounin, 10 years ago

Description: modified (diff)

comment:3 by Maxim Dounin, 10 years ago

The following patch should fix this, please test if it works for you:

# HG changeset patch
# User Maxim Dounin <mdounin@mdounin.ru>
# Date 1407610548 -14400
#      Sat Aug 09 22:55:48 2014 +0400
# Node ID b8f24832d9322f7b62649d1b10e29ebfa4f889da
# Parent  77d0fbf2bf170a14540f17b167cd68c37b5afabb
Variables: fixed nonindexed access of prefix vars (ticket #600).

Previously a configuration like

    location / {
        ssi on;
        ssi_types *;
        set $http_foo "bar";
        return 200 '<!--#echo var="http_foo" -->\n';
    }

resulted in NULL pointer dereference in ngx_http_get_variable() as
the variable was explicitly added to the variables hash, but it's
get_handler wasn't properly set in the hash.  Fix is to make sure
that get_handler is properly set by ngx_http_variables_init_vars().

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
@@ -2511,8 +2511,7 @@ ngx_http_variables_init_vars(ngx_conf_t 
 
             av = key[n].value;
 
-            if (av->get_handler
-                && v[i].name.len == key[n].key.len
+            if (v[i].name.len == key[n].key.len
                 && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len)
                    == 0)
             {
@@ -2524,6 +2523,10 @@ ngx_http_variables_init_vars(ngx_conf_t 
 
                 av->index = i;
 
+                if (av->get_handler == NULL) {
+                    break;
+                }
+
                 goto next;
             }
         }

comment:4 by Xiaochen Wang, 10 years ago

I have tested this patch. And it works well for ssi module and lua module.

comment:5 by Maxim Dounin <mdounin@…>, 10 years ago

In 6c99c5f00fc9f1c502ce4e7b1f9e3d26003f6c21/nginx:

Variables: fixed non-indexed access of prefix vars (ticket #600).

Previously, a configuration like

location / {

ssi on;
ssi_types *;
set $http_foo "bar";
return 200 '<!--#echo var="http_foo" -->\n';

}

resulted in NULL pointer dereference in ngx_http_get_variable() as
the variable was explicitly added to the variables hash, but its
get_handler wasn't properly set in the hash. Fix is to make sure
that get_handler is properly set by ngx_http_variables_init_vars().

comment:6 by Maxim Dounin, 10 years ago

Resolution: fixed
Status: assignedclosed

Fix committed, thanks.

Note: See TracTickets for help on using tickets.