mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
Limited recursion when evaluating variables.
Unlimited recursion might cause stack exhaustion in some misconfigurations.
This commit is contained in:
parent
7fab8d046e
commit
d1f524d0b3
@ -366,6 +366,9 @@ ngx_http_variable_value_t ngx_http_variable_true_value =
|
|||||||
ngx_http_variable("1");
|
ngx_http_variable("1");
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_uint_t ngx_http_variable_depth = 100;
|
||||||
|
|
||||||
|
|
||||||
ngx_http_variable_t *
|
ngx_http_variable_t *
|
||||||
ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
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_request_t *r, ngx_uint_t index)
|
|||||||
|
|
||||||
v = cmcf->variables.elts;
|
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)
|
if (v[index].get_handler(r, &r->variables[index], v[index].data)
|
||||||
== NGX_OK)
|
== NGX_OK)
|
||||||
{
|
{
|
||||||
|
ngx_http_variable_depth++;
|
||||||
|
|
||||||
if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) {
|
if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) {
|
||||||
r->variables[index].no_cacheable = 1;
|
r->variables[index].no_cacheable = 1;
|
||||||
}
|
}
|
||||||
@ -527,6 +541,8 @@ ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
|||||||
return &r->variables[index];
|
return &r->variables[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_http_variable_depth++;
|
||||||
|
|
||||||
r->variables[index].valid = 0;
|
r->variables[index].valid = 0;
|
||||||
r->variables[index].not_found = 1;
|
r->variables[index].not_found = 1;
|
||||||
|
|
||||||
@ -568,18 +584,26 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
|
|||||||
if (v) {
|
if (v) {
|
||||||
if (v->flags & NGX_HTTP_VAR_INDEXED) {
|
if (v->flags & NGX_HTTP_VAR_INDEXED) {
|
||||||
return ngx_http_get_flushed_variable(r, v->index);
|
return ngx_http_get_flushed_variable(r, v->index);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
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));
|
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||||
|
|
||||||
if (vv && v->get_handler(r, vv, v->data) == NGX_OK) {
|
if (vv && v->get_handler(r, vv, v->data) == NGX_OK) {
|
||||||
|
ngx_http_variable_depth++;
|
||||||
return vv;
|
return vv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_http_variable_depth++;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||||
if (vv == NULL) {
|
if (vv == NULL) {
|
||||||
|
@ -119,6 +119,9 @@ ngx_stream_variable_value_t ngx_stream_variable_true_value =
|
|||||||
ngx_stream_variable("1");
|
ngx_stream_variable("1");
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_uint_t ngx_stream_variable_depth = 100;
|
||||||
|
|
||||||
|
|
||||||
ngx_stream_variable_t *
|
ngx_stream_variable_t *
|
||||||
ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
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_stream_session_t *s, ngx_uint_t index)
|
|||||||
|
|
||||||
v = cmcf->variables.elts;
|
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)
|
if (v[index].get_handler(s, &s->variables[index], v[index].data)
|
||||||
== NGX_OK)
|
== NGX_OK)
|
||||||
{
|
{
|
||||||
|
ngx_stream_variable_depth++;
|
||||||
|
|
||||||
if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) {
|
if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) {
|
||||||
s->variables[index].no_cacheable = 1;
|
s->variables[index].no_cacheable = 1;
|
||||||
}
|
}
|
||||||
@ -280,6 +294,8 @@ ngx_stream_get_indexed_variable(ngx_stream_session_t *s, ngx_uint_t index)
|
|||||||
return &s->variables[index];
|
return &s->variables[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_stream_variable_depth++;
|
||||||
|
|
||||||
s->variables[index].valid = 0;
|
s->variables[index].valid = 0;
|
||||||
s->variables[index].not_found = 1;
|
s->variables[index].not_found = 1;
|
||||||
|
|
||||||
@ -322,19 +338,27 @@ ngx_stream_get_variable(ngx_stream_session_t *s, ngx_str_t *name,
|
|||||||
if (v) {
|
if (v) {
|
||||||
if (v->flags & NGX_STREAM_VAR_INDEXED) {
|
if (v->flags & NGX_STREAM_VAR_INDEXED) {
|
||||||
return ngx_stream_get_flushed_variable(s, v->index);
|
return ngx_stream_get_flushed_variable(s, v->index);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
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,
|
vv = ngx_palloc(s->connection->pool,
|
||||||
sizeof(ngx_stream_variable_value_t));
|
sizeof(ngx_stream_variable_value_t));
|
||||||
|
|
||||||
if (vv && v->get_handler(s, vv, v->data) == NGX_OK) {
|
if (vv && v->get_handler(s, vv, v->data) == NGX_OK) {
|
||||||
|
ngx_stream_variable_depth++;
|
||||||
return vv;
|
return vv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngx_stream_variable_depth++;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t));
|
vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t));
|
||||||
if (vv == NULL) {
|
if (vv == NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user