From: Sergey Kandaurov Date: Fri, 7 Aug 2020 09:34:11 +0000 (+0300) Subject: QUIC: fixed possible use-after-free on stream cleanup. X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=7d1a1fb6de71ba0ad7ac324a6c43a10a0f5d8ae6;p=nginx.git QUIC: fixed possible use-after-free on stream cleanup. A QUIC stream could be destroyed by handler while in ngx_quic_stream_input(). To detect this, ngx_quic_find_stream() is used to check that it still exists. Previously, a stream id was passed to this routine off the frame structure. In case of stream cleanup, it is freed along with other frames belonging to the stream on cleanup. Then, a cleanup handler reuses last frames to update MAX_STREAMS and serve other purpose. Thus, ngx_quic_find_stream() is passed a reused frame with zeroed out part pointed by stream_id. If a stream with id 0x0 still exists, this leads to use-after-free. --- diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c index 7c7620322..47c52067e 100644 --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -3006,6 +3006,7 @@ ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, static ngx_int_t ngx_quic_stream_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data) { + uint64_t id; ngx_buf_t *b; ngx_event_t *rev; ngx_quic_stream_t *sn; @@ -3016,6 +3017,7 @@ ngx_quic_stream_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data) sn = data; f = &frame->u.stream; + id = f->stream_id; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic existing stream"); @@ -3046,7 +3048,7 @@ ngx_quic_stream_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data) } /* check if stream was destroyed by handler */ - if (ngx_quic_find_stream(&qc->streams.tree, f->stream_id) == NULL) { + if (ngx_quic_find_stream(&qc->streams.tree, id) == NULL) { return NGX_DONE; }