# HG changeset patch
# User Roman Arutyunyan <arut@nginx.com>
# Date 1442578460 -10800
# Fri Sep 18 15:14:20 2015 +0300
# Node ID de3b5bc41b8623e6f3fd9f670e5a92fc1a84701e
# Parent 257b51c37c5a76559d50c2a44011a7d3f45bd4b9
Prevented posted requests from running recursively (ticket #788).
When ngx_http_run_posted_requests() is called from a resolve handler after
a cached result is found, it runs the next posted request. That request,
in turn, can follow the same code path and make the next recursive call of
ngx_http_run_posted_requests(). If a big number of requests was posted,
this can finally lead to stack overflow and nginx crash.
diff -r 257b51c37c5a -r de3b5bc41b86 src/http/ngx_http_request.c
|
a
|
b
|
ngx_http_run_posted_requests(ngx_connect
|
| 2195 | 2195 | ngx_http_request_t *r; |
| 2196 | 2196 | ngx_http_posted_request_t *pr; |
| 2197 | 2197 | |
| | 2198 | if (c->destroyed) { |
| | 2199 | return; |
| | 2200 | } |
| | 2201 | |
| | 2202 | r = c->data; |
| | 2203 | |
| | 2204 | if (r->main->running_posted) { |
| | 2205 | return; |
| | 2206 | } |
| | 2207 | |
| | 2208 | r->main->running_posted = 1; |
| | 2209 | |
| 2198 | 2210 | for ( ;; ) { |
| 2199 | 2211 | |
| | 2212 | r = c->data; |
| | 2213 | pr = r->main->posted_requests; |
| | 2214 | |
| | 2215 | if (pr == NULL) { |
| | 2216 | r->main->running_posted = 0; |
| | 2217 | return; |
| | 2218 | } |
| | 2219 | |
| | 2220 | r->main->posted_requests = pr->next; |
| | 2221 | |
| | 2222 | r = pr->request; |
| | 2223 | |
| | 2224 | ngx_http_set_log_request(c->log, r); |
| | 2225 | |
| | 2226 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
| | 2227 | "http posted request: \"%V?%V\"", &r->uri, &r->args); |
| | 2228 | |
| | 2229 | r->write_event_handler(r); |
| | 2230 | |
| 2200 | 2231 | if (c->destroyed) { |
| 2201 | 2232 | return; |
| 2202 | 2233 | } |
| 2203 | | |
| 2204 | | r = c->data; |
| 2205 | | pr = r->main->posted_requests; |
| 2206 | | |
| 2207 | | if (pr == NULL) { |
| 2208 | | return; |
| 2209 | | } |
| 2210 | | |
| 2211 | | r->main->posted_requests = pr->next; |
| 2212 | | |
| 2213 | | r = pr->request; |
| 2214 | | |
| 2215 | | ngx_http_set_log_request(c->log, r); |
| 2216 | | |
| 2217 | | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
| 2218 | | "http posted request: \"%V?%V\"", &r->uri, &r->args); |
| 2219 | | |
| 2220 | | r->write_event_handler(r); |
| 2221 | 2234 | } |
| 2222 | 2235 | } |
| 2223 | 2236 | |
diff -r 257b51c37c5a -r de3b5bc41b86 src/http/ngx_http_request.h
|
a
|
b
|
struct ngx_http_request_s {
|
| 523 | 523 | unsigned root_tested:1; |
| 524 | 524 | unsigned done:1; |
| 525 | 525 | unsigned logged:1; |
| | 526 | unsigned running_posted:1; |
| 526 | 527 | |
| 527 | 528 | unsigned buffered:4; |
| 528 | 529 | |