summaryrefslogtreecommitdiffhomepage
path: root/src/http/v3/ngx_http_v3_uni.c
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2024-05-28 17:18:28 +0400
committerRoman Arutyunyan <arut@nginx.com>2024-05-28 17:18:28 +0400
commit326150b82d5a345dfb8799f2f52e987760ea242e (patch)
tree5c1578eb6050e89dd2eb6459ec4c6828af4a4186 /src/http/v3/ngx_http_v3_uni.c
parenteaa6daa5f5d79c0e34aa1a08faef3c574e46d613 (diff)
downloadnginx-326150b82d5a345dfb8799f2f52e987760ea242e.tar.gz
nginx-326150b82d5a345dfb8799f2f52e987760ea242e.tar.bz2
HTTP/3: decoder stream pre-creation.
Previously a decoder stream was created on demand for sending Section Acknowledgement, Stream Cancellation and Insert Count Increment. If conditions for sending any of these instructions never happen, a decoder stream is not created at all. These conditions include client not using the dynamic table and no streams abandoned by server (RFC 9204, Section 2.2.2.2). However RFC 9204, Section 4.2 defines only one condition for not creating a decoder stream: An endpoint MAY avoid creating a decoder stream if its decoder sets the maximum capacity of the dynamic table to zero. The change enables pre-creation of the decoder stream at HTTP/3 session initialization if maximum dynamic table capacity is not zero. Note that this value is currently hardcoded to 4096 bytes and is not configurable, so the stream is now always created. Also, the change fixes a potential stack overflow when creating a decoder stream in ngx_http_v3_send_cancel_stream() while draining a request stream by ngx_drain_connections(). Creating a decoder stream involves calling ngx_get_connection(), which calls ngx_drain_connections(), which will drain the same request stream again. If client's MAX_STREAMS for uni stream is high enough, these recursive calls will continue until we run out of stack. Otherwise, decoder stream creation will fail at some point and the request stream connection will be drained. This may result in use-after-free, since this connection could still be referenced up the stack.
Diffstat (limited to 'src/http/v3/ngx_http_v3_uni.c')
-rw-r--r--src/http/v3/ngx_http_v3_uni.c4
1 files changed, 1 insertions, 3 deletions
diff --git a/src/http/v3/ngx_http_v3_uni.c b/src/http/v3/ngx_http_v3_uni.c
index 2fc5b07a4..302064b8b 100644
--- a/src/http/v3/ngx_http_v3_uni.c
+++ b/src/http/v3/ngx_http_v3_uni.c
@@ -20,8 +20,6 @@ static void ngx_http_v3_close_uni_stream(ngx_connection_t *c);
static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
static void ngx_http_v3_uni_dummy_read_handler(ngx_event_t *wev);
static void ngx_http_v3_uni_dummy_write_handler(ngx_event_t *wev);
-static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c,
- ngx_uint_t type);
void
@@ -307,7 +305,7 @@ ngx_http_v3_uni_dummy_write_handler(ngx_event_t *wev)
}
-static ngx_connection_t *
+ngx_connection_t *
ngx_http_v3_get_uni_stream(ngx_connection_t *c, ngx_uint_t type)
{
u_char buf[NGX_HTTP_V3_VARLEN_INT_LEN];