Mercurial > hg > nginx
comparison src/http/ngx_http_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 | b3b7e33083ac |
children | d2b2ff157da5 |
comparison
equal
deleted
inserted
replaced
6850:41cb1b64561d | 6851:8cd97c14b0e2 |
---|---|
364 ngx_http_variable(""); | 364 ngx_http_variable(""); |
365 ngx_http_variable_value_t ngx_http_variable_true_value = | 365 ngx_http_variable_value_t ngx_http_variable_true_value = |
366 ngx_http_variable("1"); | 366 ngx_http_variable("1"); |
367 | 367 |
368 | 368 |
369 static ngx_uint_t ngx_http_variable_depth = 100; | |
370 | |
371 | |
369 ngx_http_variable_t * | 372 ngx_http_variable_t * |
370 ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) | 373 ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) |
371 { | 374 { |
372 ngx_int_t rc; | 375 ngx_int_t rc; |
373 ngx_uint_t i; | 376 ngx_uint_t i; |
515 return &r->variables[index]; | 518 return &r->variables[index]; |
516 } | 519 } |
517 | 520 |
518 v = cmcf->variables.elts; | 521 v = cmcf->variables.elts; |
519 | 522 |
523 if (ngx_http_variable_depth == 0) { | |
524 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
525 "cycle while evaluating variable \"%V\"", | |
526 &v[index].name); | |
527 return NULL; | |
528 } | |
529 | |
530 ngx_http_variable_depth--; | |
531 | |
520 if (v[index].get_handler(r, &r->variables[index], v[index].data) | 532 if (v[index].get_handler(r, &r->variables[index], v[index].data) |
521 == NGX_OK) | 533 == NGX_OK) |
522 { | 534 { |
535 ngx_http_variable_depth++; | |
536 | |
523 if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) { | 537 if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) { |
524 r->variables[index].no_cacheable = 1; | 538 r->variables[index].no_cacheable = 1; |
525 } | 539 } |
526 | 540 |
527 return &r->variables[index]; | 541 return &r->variables[index]; |
528 } | 542 } |
543 | |
544 ngx_http_variable_depth++; | |
529 | 545 |
530 r->variables[index].valid = 0; | 546 r->variables[index].valid = 0; |
531 r->variables[index].not_found = 1; | 547 r->variables[index].not_found = 1; |
532 | 548 |
533 return NULL; | 549 return NULL; |
566 v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len); | 582 v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len); |
567 | 583 |
568 if (v) { | 584 if (v) { |
569 if (v->flags & NGX_HTTP_VAR_INDEXED) { | 585 if (v->flags & NGX_HTTP_VAR_INDEXED) { |
570 return ngx_http_get_flushed_variable(r, v->index); | 586 return ngx_http_get_flushed_variable(r, v->index); |
571 | 587 } |
572 } else { | 588 |
573 | 589 if (ngx_http_variable_depth == 0) { |
574 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 590 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
575 | 591 "cycle while evaluating variable \"%V\"", name); |
576 if (vv && v->get_handler(r, vv, v->data) == NGX_OK) { | |
577 return vv; | |
578 } | |
579 | |
580 return NULL; | 592 return NULL; |
581 } | 593 } |
594 | |
595 ngx_http_variable_depth--; | |
596 | |
597 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | |
598 | |
599 if (vv && v->get_handler(r, vv, v->data) == NGX_OK) { | |
600 ngx_http_variable_depth++; | |
601 return vv; | |
602 } | |
603 | |
604 ngx_http_variable_depth++; | |
605 return NULL; | |
582 } | 606 } |
583 | 607 |
584 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 608 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
585 if (vv == NULL) { | 609 if (vv == NULL) { |
586 return NULL; | 610 return NULL; |