]> git.kaiwu.me - nginx.git/commit
Event pipe: do not free buffers still used by the downstream
authorIvan Ovchinnikov <i.ovchinnikov@f5.com>
Fri, 21 Aug 2026 20:48:15 +0000 (20:48 +0000)
committerIvan Ovchinnikov <33402471+route443@users.noreply.github.com>
Wed, 26 Aug 2026 02:16:57 +0000 (19:16 -0700)
commit8fa349cef4c1760be9a1acad629cc087f802bb14
tree0636172f77f440eb6ae03987b75323a49d80a7c2
parent028c0fab847a9b3552130682352ac890f41f7550
Event pipe: do not free buffers still used by the downstream

When a body filter returned an error, ngx_event_pipe_drain_chains()
returned all buffers to p->free_raw_bufs, including those in p->busy,
which are still owned by the downstream. If upstream EOF was detected
in the same ngx_event_pipe() pass, ngx_event_pipe_read_upstream() then
freed them while still referenced. With HTTP/2 only the stream's fake
connection is marked on error, so ngx_http_v2_send_output_queue() kept
sending DATA frames pointing at the freed buffers, a use-after-free.

Fixed by keeping the p->busy chains intact, the buffers are freed with
the request pool.  This also stops the pipe from reusing them for new
upstream reads, which previously could overwrite response body data
still queued for the client.  Additionally, the pipe no longer treats
a downstream it has given up on as merely blocked, so the loop is
still guaranteed to terminate.

Co-authored-by: Roman Arutyunyan <arut@nginx.com>
src/event/ngx_event_pipe.c