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;