diff --git a/SOURCES/0021-Rewrite-fix-buffer-overflow-with-overlapping-capture.patch b/SOURCES/0021-Rewrite-fix-buffer-overflow-with-overlapping-capture.patch new file mode 100644 index 0000000..d2f3607 --- /dev/null +++ b/SOURCES/0021-Rewrite-fix-buffer-overflow-with-overlapping-capture.patch @@ -0,0 +1,72 @@ +From 63505bbd21c6ed3a2e6fafdaa1ed305ddbf3e81e Mon Sep 17 00:00:00 2001 +From: Roman Arutyunyan +Date: Thu, 14 May 2026 18:42:18 +0400 +Subject: [PATCH] Rewrite: fix buffer overflow with overlapping captures + +When the rewrite replacement string had no variables, but had +overlapping captures, the length of the allocated buffer could be +smaller than the replacement string. This could happen either +when the "redirect" parameter is specified, or when arguments are +present in the replacement string. + +The following configurations resulted in heap buffer overflow when +using URI "/++++++++++++++++++++++++++++++": + + location / { + rewrite ^/((.*))$ http://127.0.0.1:8080/$1$2 redirect; + return 200 foo; + } + + location / { + rewrite ^/((.*))$ http://127.0.0.1:8080/?$1$2; + return 200 foo; + } + +Reported by Mufeed VH of Winfunc Research. +--- + src/http/ngx_http_script.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c +index 302f842..d13ca2d 100644 +--- a/src/http/ngx_http_script.c ++++ b/src/http/ngx_http_script.c +@@ -999,6 +999,8 @@ ngx_http_script_start_args_code(ngx_http_script_engine_t *e) + void + ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) + { ++ int *cap; ++ u_char *p; + size_t len; + ngx_int_t rc; + ngx_uint_t n; +@@ -1105,15 +1107,19 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e) + if (code->lengths == NULL) { + e->buf.len = code->size; + +- if (code->uri) { +- if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) { +- e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, +- NGX_ESCAPE_ARGS); +- } +- } ++ cap = r->captures; ++ p = r->captures_data; + + for (n = 2; n < r->ncaptures; n += 2) { +- e->buf.len += r->captures[n + 1] - r->captures[n]; ++ e->buf.len += cap[n + 1] - cap[n]; ++ ++ if (code->uri) { ++ if (r->quoted_uri || r->plus_in_uri) { ++ e->buf.len += 2 * ngx_escape_uri(NULL, &p[cap[n]], ++ cap[n + 1] - cap[n], ++ NGX_ESCAPE_ARGS); ++ } ++ } + } + + } else { +-- +2.44.0 + diff --git a/SOURCES/0022-Added-max_headers-directive.patch b/SOURCES/0022-Added-max_headers-directive.patch new file mode 100644 index 0000000..818dc65 --- /dev/null +++ b/SOURCES/0022-Added-max_headers-directive.patch @@ -0,0 +1,126 @@ +From edb82a3e2388938f6230731e1f50e98fbde5f83f Mon Sep 17 00:00:00 2001 +From: Maxim Dounin +Date: Fri, 24 May 2024 00:20:01 +0300 +Subject: [PATCH] Added max_headers directive. + +The directive limits the number of request headers accepted from clients. +While the total amount of headers is believed to be sufficiently limited +by the existing buffer size limits (client_header_buffer_size and +large_client_header_buffers), the additional limit on the number of headers +might be beneficial to better protect backend servers. + +Requested by Maksim Yevmenkin. + +Signed-off-by: Elijah Zupancic +Origin: +--- + src/http/ngx_http_core_module.c | 10 ++++++++++ + src/http/ngx_http_core_module.h | 2 ++ + src/http/ngx_http_request.c | 9 +++++++++ + src/http/ngx_http_request.h | 1 + + src/http/v2/ngx_http_v2.c | 9 +++++++++ + 5 files changed, 31 insertions(+) + +diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c +index 6664fa6..2516331 100644 +--- a/src/http/ngx_http_core_module.c ++++ b/src/http/ngx_http_core_module.c +@@ -252,6 +252,13 @@ static ngx_command_t ngx_http_core_commands[] = { + offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers), + NULL }, + ++ { ngx_string("max_headers"), ++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ++ ngx_conf_set_num_slot, ++ NGX_HTTP_SRV_CONF_OFFSET, ++ offsetof(ngx_http_core_srv_conf_t, max_headers), ++ NULL }, ++ + { ngx_string("ignore_invalid_headers"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, +@@ -3370,6 +3377,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf) + cscf->request_pool_size = NGX_CONF_UNSET_SIZE; + cscf->client_header_timeout = NGX_CONF_UNSET_MSEC; + cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE; ++ cscf->max_headers = NGX_CONF_UNSET_UINT; + cscf->ignore_invalid_headers = NGX_CONF_UNSET; + cscf->merge_slashes = NGX_CONF_UNSET; + cscf->underscores_in_headers = NGX_CONF_UNSET; +@@ -3411,6 +3419,8 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + return NGX_CONF_ERROR; + } + ++ ngx_conf_merge_uint_value(conf->max_headers, prev->max_headers, 1000); ++ + ngx_conf_merge_value(conf->ignore_invalid_headers, + prev->ignore_invalid_headers, 1); + +diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h +index 2341fd4..2e787e2 100644 +--- a/src/http/ngx_http_core_module.h ++++ b/src/http/ngx_http_core_module.h +@@ -196,6 +196,8 @@ typedef struct { + + ngx_msec_t client_header_timeout; + ++ ngx_uint_t max_headers; ++ + ngx_flag_t ignore_invalid_headers; + ngx_flag_t merge_slashes; + ngx_flag_t underscores_in_headers; +diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c +index 404aa77..dccc9de 100644 +--- a/src/http/ngx_http_request.c ++++ b/src/http/ngx_http_request.c +@@ -1468,6 +1468,15 @@ ngx_http_process_request_headers(ngx_event_t *rev) + + /* a header line has been parsed successfully */ + ++ if (r->headers_in.count++ >= cscf->max_headers) { ++ r->lingering_close = 1; ++ ngx_log_error(NGX_LOG_INFO, c->log, 0, ++ "client sent too many header lines"); ++ ngx_http_finalize_request(r, ++ NGX_HTTP_REQUEST_HEADER_TOO_LARGE); ++ break; ++ } ++ + h = ngx_list_push(&r->headers_in.headers); + if (h == NULL) { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); +diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h +index 6dfb4a4..3b46c41 100644 +--- a/src/http/ngx_http_request.h ++++ b/src/http/ngx_http_request.h +@@ -180,6 +180,7 @@ typedef struct { + + typedef struct { + ngx_list_t headers; ++ ngx_uint_t count; + + ngx_table_elt_t *host; + ngx_table_elt_t *connection; +diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c +index 291677a..7812ddc 100644 +--- a/src/http/v2/ngx_http_v2.c ++++ b/src/http/v2/ngx_http_v2.c +@@ -1860,6 +1860,15 @@ ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos, + } + + } else { ++ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); ++ ++ if (r->headers_in.count++ >= cscf->max_headers) { ++ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, ++ "client sent too many header lines"); ++ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE); ++ goto error; ++ } ++ + h = ngx_list_push(&r->headers_in.headers); + if (h == NULL) { + return ngx_http_v2_connection_error(h2c, +-- +2.44.0 + diff --git a/SPECS/nginx.spec b/SPECS/nginx.spec index 88faef4..e61ee50 100644 --- a/SPECS/nginx.spec +++ b/SPECS/nginx.spec @@ -41,7 +41,7 @@ Name: nginx Epoch: 2 Version: 1.20.1 -Release: 28%{?dist}.2.alma.1 +Release: 28%{?dist}.3.alma.1 Summary: A high performance web server and reverse proxy server # BSD License (two clause) @@ -144,6 +144,14 @@ Patch19: 0019-Mp4-avoid-zero-size-buffers-in-output.patch # upstream patch - https://github.com/nginx/nginx/commit/524977e7 Patch20: 0020-Rewrite-fixed-escaping-and-possible-buffer-overrun.patch +# https://redhat.atlassian.net/browse/RHEL-178669 +# upstream patch - https://github.com/nginx/nginx/commit/ca4f92a27464ae6c2082245e4f67048c633aa032 +Patch21: 0021-Rewrite-fix-buffer-overflow-with-overlapping-capture.patch + +# https://redhat.atlassian.net/browse/RHEL-182544 +# upstream patch - https://github.com/nginx/nginx/commit/365694160a85229a7cb006738de9260d49ff5fa2 +Patch22: 0022-Added-max_headers-directive.patch + BuildRequires: make BuildRequires: gcc BuildRequires: gnupg2 @@ -660,9 +668,15 @@ fi %changelog -* Wed May 20 2026 Eduard Abdullin - 2:1.20.1-28.2.alma.1 +* Thu Jun 25 2026 Eduard Abdullin - 2:1.20.1-28.3.alma.1 - Debrand for AlmaLinux +* Mon Jun 08 2026 Luboš Uhliarik - 2:1.20.1-28.3 +- Resolves: RHEL-178684 - nginx: code execution and denial of + service (CVE-2026-9256) +- Resolves: RHEL-182553 - nginx: HTTP/2: Remote Denial of Service via + compression bomb and Slowloris-style attack + * Thu May 14 2026 Luboš Uhliarik - 2:1.20.1-28.2 - Resolves: RHEL-176232 - nginx: NGINX: Arbitrary Code Execution Vulnerability (CVE-2026-42945)