Welcome! Log In Create A New Profile

Advanced

[nginx] Limited recursion when evaluating variables.

December 22, 2016 02:02AM
details: http://hg.nginx.org/nginx/rev/8cd97c14b0e2
branches:
changeset: 6851:8cd97c14b0e2
user: Ruslan Ermilov <ru@nginx.com>
date: Wed Dec 21 22:01:24 2016 +0300
description:
Limited recursion when evaluating variables.

Unlimited recursion might cause stack exhaustion in some misconfigurations.

diffstat:

src/http/ngx_http_variables.c | 42 ++++++++++++++++++++++++++++++--------
src/stream/ngx_stream_variables.c | 42 ++++++++++++++++++++++++++++++--------
2 files changed, 66 insertions(+), 18 deletions(-)

diffs (157 lines):

diff -r 41cb1b64561d -r 8cd97c14b0e2 src/http/ngx_http_variables.c
--- a/src/http/ngx_http_variables.c Tue Dec 20 12:05:14 2016 +0300
+++ b/src/http/ngx_http_variables.c Wed Dec 21 22:01:24 2016 +0300
@@ -366,6 +366,9 @@ ngx_http_variable_value_t ngx_http_vari
ngx_http_variable("1");


+static ngx_uint_t ngx_http_variable_depth = 100;
+
+
ngx_http_variable_t *
ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
{
@@ -517,9 +520,20 @@ ngx_http_get_indexed_variable(ngx_http_r

v = cmcf->variables.elts;

+ if (ngx_http_variable_depth == 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "cycle while evaluating variable \"%V\"",
+ &v[index].name);
+ return NULL;
+ }
+
+ ngx_http_variable_depth--;
+
if (v[index].get_handler(r, &r->variables[index], v[index].data)
== NGX_OK)
{
+ ngx_http_variable_depth++;
+
if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) {
r->variables[index].no_cacheable = 1;
}
@@ -527,6 +541,8 @@ ngx_http_get_indexed_variable(ngx_http_r
return &r->variables[index];
}

+ ngx_http_variable_depth++;
+
r->variables[index].valid = 0;
r->variables[index].not_found = 1;

@@ -568,17 +584,25 @@ ngx_http_get_variable(ngx_http_request_t
if (v) {
if (v->flags & NGX_HTTP_VAR_INDEXED) {
return ngx_http_get_flushed_variable(r, v->index);
-
- } else {
-
- vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
-
- if (vv && v->get_handler(r, vv, v->data) == NGX_OK) {
- return vv;
- }
-
+ }
+
+ if (ngx_http_variable_depth == 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "cycle while evaluating variable \"%V\"", name);
return NULL;
}
+
+ ngx_http_variable_depth--;
+
+ vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
+
+ if (vv && v->get_handler(r, vv, v->data) == NGX_OK) {
+ ngx_http_variable_depth++;
+ return vv;
+ }
+
+ ngx_http_variable_depth++;
+ return NULL;
}

vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
diff -r 41cb1b64561d -r 8cd97c14b0e2 src/stream/ngx_stream_variables.c
--- a/src/stream/ngx_stream_variables.c Tue Dec 20 12:05:14 2016 +0300
+++ b/src/stream/ngx_stream_variables.c Wed Dec 21 22:01:24 2016 +0300
@@ -119,6 +119,9 @@ ngx_stream_variable_value_t ngx_stream_
ngx_stream_variable("1");


+static ngx_uint_t ngx_stream_variable_depth = 100;
+
+
ngx_stream_variable_t *
ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
{
@@ -270,9 +273,20 @@ ngx_stream_get_indexed_variable(ngx_stre

v = cmcf->variables.elts;

+ if (ngx_stream_variable_depth == 0) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "cycle while evaluating variable \"%V\"",
+ &v[index].name);
+ return NULL;
+ }
+
+ ngx_stream_variable_depth--;
+
if (v[index].get_handler(s, &s->variables[index], v[index].data)
== NGX_OK)
{
+ ngx_stream_variable_depth++;
+
if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) {
s->variables[index].no_cacheable = 1;
}
@@ -280,6 +294,8 @@ ngx_stream_get_indexed_variable(ngx_stre
return &s->variables[index];
}

+ ngx_stream_variable_depth++;
+
s->variables[index].valid = 0;
s->variables[index].not_found = 1;

@@ -322,18 +338,26 @@ ngx_stream_get_variable(ngx_stream_sessi
if (v) {
if (v->flags & NGX_STREAM_VAR_INDEXED) {
return ngx_stream_get_flushed_variable(s, v->index);
-
- } else {
+ }

- vv = ngx_palloc(s->connection->pool,
- sizeof(ngx_stream_variable_value_t));
-
- if (vv && v->get_handler(s, vv, v->data) == NGX_OK) {
- return vv;
- }
-
+ if (ngx_stream_variable_depth == 0) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "cycle while evaluating variable \"%V\"", name);
return NULL;
}
+
+ ngx_stream_variable_depth--;
+
+ vv = ngx_palloc(s->connection->pool,
+ sizeof(ngx_stream_variable_value_t));
+
+ if (vv && v->get_handler(s, vv, v->data) == NGX_OK) {
+ ngx_stream_variable_depth++;
+ return vv;
+ }
+
+ ngx_stream_variable_depth++;
+ return NULL;
}

vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t));
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] Limited recursion when evaluating variables.

ru@nginx.com 1595 December 22, 2016 02:02AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 209
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready