Mercurial > hg > nginx
annotate src/http/v2/ngx_http_v2_encode.c @ 9286:d9fe808c1841 default tip
HTTP/3: protection from recursion during connection reuse.
When draining a connection associated with an HTTP/3 stream, calling
ngx_http_v3_send_cancel_stream() might result in an attempt to obtain
a connection for the decoder stream. This in turn will trigger draining
of the very same connection. Depending on the client settings, this
might either lead to stack overflow or will end up in decoder stream
creation error and destroying the connection at some point, potentially
resulting in use-after-free on stack.
Fix is to make sure that connection reuse is disabled in
ngx_http_v3_reset_stream(), so the recursion in question won't happen
regardless of what called functions do.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 02 Jun 2024 23:51:55 +0300 |
parents | 336084ff943b |
children |
rev | line source |
---|---|
7229
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
1 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
2 /* |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
3 * Copyright (C) Nginx, Inc. |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
4 * Copyright (C) Valentin V. Bartenev |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
5 */ |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
6 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
7 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
10 #include <ngx_http.h> |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
11 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
12 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
13 static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
14 ngx_uint_t value); |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
15 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
16 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
17 u_char * |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
18 ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp, |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
19 ngx_uint_t lower) |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
20 { |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
21 size_t hlen; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
22 |
7977
336084ff943b
Moved Huffman coding out of HTTP/2.
Ruslan Ermilov <ru@nginx.com>
parents:
7229
diff
changeset
|
23 hlen = ngx_http_huff_encode(src, len, tmp, lower); |
7229
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
24 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
25 if (hlen > 0) { |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
26 *dst = NGX_HTTP_V2_ENCODE_HUFF; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
27 dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), hlen); |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
28 return ngx_cpymem(dst, tmp, hlen); |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
29 } |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
30 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
31 *dst = NGX_HTTP_V2_ENCODE_RAW; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
32 dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), len); |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
33 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
34 if (lower) { |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
35 ngx_strlow(dst, src, len); |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
36 return dst + len; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
37 } |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
38 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
39 return ngx_cpymem(dst, src, len); |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
40 } |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
41 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
42 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
43 static u_char * |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
44 ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value) |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
45 { |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
46 if (value < prefix) { |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
47 *pos++ |= value; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
48 return pos; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
49 } |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
50 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
51 *pos++ |= prefix; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
52 value -= prefix; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
53 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
54 while (value >= 128) { |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
55 *pos++ = value % 128 + 128; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
56 value /= 128; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
57 } |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
58 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
59 *pos++ = (u_char) value; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
60 |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
61 return pos; |
87e9e4aabf1b
HTTP/2: externalized various constants and interfaces.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
62 } |