-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Fixed request counting with subrequests in case of error. #515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Could you please elaborate more on how exactly to reproduce this issue? From the branch name it follows that the primary way to do it is by using the ssi module. Just triggering the error in the code and running Normally, a subrequest error finalizes the entire main request (see addition for example). In this case Looks like a simple way to access a request from |
Indeed, both cases are explained by proxied subrequests initiated by SSI "virtual" command,
In the basic scenario, with a single failing subrequest, request count zero alerts are papered over by r->count reset to 1 in ngx_http_terminate_handler(). With two included requests in ssi.html the behaviour is different, such as in:
Here, after failing 1st subrequest, the 2nd is run posted. Then the 1st (active) subrequest will be normally run on upstream write event. Eventually, after normal processing and finalizing both subrequests, r->count is zero. In addition to the above, consider the 1st failing subrequest finished its processing first (or it served static content), and a parent request was awaken, where it then posts 2nd subrequest from the postpone filter. Here, ngx_http_post_request() additional error results in main request termination with terminate request count:1. This calls in turn all cleanup handlers including registered from subrequests. Such one is ngx_http_upstream_cleanup() for the 2nd subrequest, which may end up in ngx_http_finalize_request(NGX_DONE), and due to the wrong request count, in ngx_http_close_request() for the main request, which ultimately will destroy request pool. Sanitizer catches this U-A-F on the next cln->next, otherwise it may or may not segfault depending on how far the freed request was damaged. |
Changing SSI module behaviour to return NGX_ERROR looks like a separate change, which might have pitfails. |
The patch looks ok, as discussed before. However, I think the commit log needs a clarification about the fact that the issue only manifests itself with the ssi module, which ignores As mentioned above, fixing the ssi module to treat such errors as fatal could be an alternative solution. However, |
Previously, request might be left in inconsistent state in case of error, which manifested in "http request count is zero" alerts when used by SSI filter. The fix is to reshuffle initialization order to postpone committing state changes until after any potentially failing parts. Found by bad memory allocator simulation.
Agree, I don't like commit log either. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks ok.
Previously, when creating a subrequest, request count increment could be missed in case of error after it became active. This resulted in "http request count is zero" alerts and socket leaks.
Further, if posting the next subrequest resulted in an error, then as part of the main request termination, request pool could be destroyed from a subrequest cleanup handler due to the wrong request reference count, followed by a segmentation fault.
Found by bad memory allocator simulation.