Mercurial > hg > nginx
comparison src/stream/ngx_stream_variables.c @ 6851:8cd97c14b0e2
Limited recursion when evaluating variables.
Unlimited recursion might cause stack exhaustion in some misconfigurations.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Wed, 21 Dec 2016 22:01:24 +0300 |
parents | b9f78a4e3597 |
children | d2b2ff157da5 |
comparison
equal
deleted
inserted
replaced
6850:41cb1b64561d | 6851:8cd97c14b0e2 |
---|---|
115 | 115 |
116 ngx_stream_variable_value_t ngx_stream_variable_null_value = | 116 ngx_stream_variable_value_t ngx_stream_variable_null_value = |
117 ngx_stream_variable(""); | 117 ngx_stream_variable(""); |
118 ngx_stream_variable_value_t ngx_stream_variable_true_value = | 118 ngx_stream_variable_value_t ngx_stream_variable_true_value = |
119 ngx_stream_variable("1"); | 119 ngx_stream_variable("1"); |
120 | |
121 | |
122 static ngx_uint_t ngx_stream_variable_depth = 100; | |
120 | 123 |
121 | 124 |
122 ngx_stream_variable_t * | 125 ngx_stream_variable_t * |
123 ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) | 126 ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) |
124 { | 127 { |
268 return &s->variables[index]; | 271 return &s->variables[index]; |
269 } | 272 } |
270 | 273 |
271 v = cmcf->variables.elts; | 274 v = cmcf->variables.elts; |
272 | 275 |
276 if (ngx_stream_variable_depth == 0) { | |
277 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
278 "cycle while evaluating variable \"%V\"", | |
279 &v[index].name); | |
280 return NULL; | |
281 } | |
282 | |
283 ngx_stream_variable_depth--; | |
284 | |
273 if (v[index].get_handler(s, &s->variables[index], v[index].data) | 285 if (v[index].get_handler(s, &s->variables[index], v[index].data) |
274 == NGX_OK) | 286 == NGX_OK) |
275 { | 287 { |
288 ngx_stream_variable_depth++; | |
289 | |
276 if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) { | 290 if (v[index].flags & NGX_STREAM_VAR_NOCACHEABLE) { |
277 s->variables[index].no_cacheable = 1; | 291 s->variables[index].no_cacheable = 1; |
278 } | 292 } |
279 | 293 |
280 return &s->variables[index]; | 294 return &s->variables[index]; |
281 } | 295 } |
296 | |
297 ngx_stream_variable_depth++; | |
282 | 298 |
283 s->variables[index].valid = 0; | 299 s->variables[index].valid = 0; |
284 s->variables[index].not_found = 1; | 300 s->variables[index].not_found = 1; |
285 | 301 |
286 return NULL; | 302 return NULL; |
320 v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len); | 336 v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len); |
321 | 337 |
322 if (v) { | 338 if (v) { |
323 if (v->flags & NGX_STREAM_VAR_INDEXED) { | 339 if (v->flags & NGX_STREAM_VAR_INDEXED) { |
324 return ngx_stream_get_flushed_variable(s, v->index); | 340 return ngx_stream_get_flushed_variable(s, v->index); |
325 | 341 } |
326 } else { | 342 |
327 | 343 if (ngx_stream_variable_depth == 0) { |
328 vv = ngx_palloc(s->connection->pool, | 344 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
329 sizeof(ngx_stream_variable_value_t)); | 345 "cycle while evaluating variable \"%V\"", name); |
330 | |
331 if (vv && v->get_handler(s, vv, v->data) == NGX_OK) { | |
332 return vv; | |
333 } | |
334 | |
335 return NULL; | 346 return NULL; |
336 } | 347 } |
348 | |
349 ngx_stream_variable_depth--; | |
350 | |
351 vv = ngx_palloc(s->connection->pool, | |
352 sizeof(ngx_stream_variable_value_t)); | |
353 | |
354 if (vv && v->get_handler(s, vv, v->data) == NGX_OK) { | |
355 ngx_stream_variable_depth++; | |
356 return vv; | |
357 } | |
358 | |
359 ngx_stream_variable_depth++; | |
360 return NULL; | |
337 } | 361 } |
338 | 362 |
339 vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t)); | 363 vv = ngx_palloc(s->connection->pool, sizeof(ngx_stream_variable_value_t)); |
340 if (vv == NULL) { | 364 if (vv == NULL) { |
341 return NULL; | 365 return NULL; |