Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions SPECS/nginx/CVE-2026-40460.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
From 31e8f95c09861ab0d184dc71ad47af4dfcf62ba1 Mon Sep 17 00:00:00 2001
From: Roman Arutyunyan <arut@nginx.com>
Date: Thu, 30 Apr 2026 17:15:53 +0400
Subject: [PATCH] QUIC: avoid assigning unvalidated address to new streams

Previously, when a client migrated to a new address, new QUIC streams
received this address before validation. This allowed an attacker to
create QUIC streams with a spoofed address.

Reported by Rodrigo Laneth.

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/nginx/nginx/commit/5461e8bbc09230a4cf8e3d7737c176ae69b091f1.patch
---
src/event/quic/ngx_event_quic_migration.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/event/quic/ngx_event_quic_migration.c b/src/event/quic/ngx_event_quic_migration.c
index 6befc34..16bad46 100644
--- a/src/event/quic/ngx_event_quic_migration.c
+++ b/src/event/quic/ngx_event_quic_migration.c
@@ -194,6 +194,8 @@ valid:

path->validated = 1;

+ ngx_quic_set_connection_path(c, path);
+
if (path->mtu_unvalidated) {
path->mtu_unvalidated = 0;
return ngx_quic_validate_path(c, path);
@@ -511,9 +513,10 @@ ngx_quic_handle_migration(ngx_connection_t *c, ngx_quic_header_t *pkt)
qc->path = next;
qc->path->tag = NGX_QUIC_PATH_ACTIVE;

- ngx_quic_set_connection_path(c, next);
+ if (next->validated) {
+ ngx_quic_set_connection_path(c, next);

- if (!next->validated && next->state != NGX_QUIC_PATH_VALIDATING) {
+ } else if (next->state != NGX_QUIC_PATH_VALIDATING) {
if (ngx_quic_validate_path(c, next) != NGX_OK) {
return NGX_ERROR;
}
@@ -807,8 +810,6 @@ ngx_quic_expire_path_validation(ngx_connection_t *c, ngx_quic_path_t *path)
qc->path = bkp;
qc->path->tag = NGX_QUIC_PATH_ACTIVE;

- ngx_quic_set_connection_path(c, qc->path);
-
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"quic path seq:%uL addr:%V is restored from backup",
qc->path->seqnum, &qc->path->addr_text);
--
2.45.4

72 changes: 72 additions & 0 deletions SPECS/nginx/CVE-2026-40701.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
From 7e739b1e54a4ae485c1ea5114ce9fed33d3399a5 Mon Sep 17 00:00:00 2001
From: Roman Arutyunyan <arut@nginx.com>
Date: Tue, 21 Apr 2026 14:51:41 +0400
Subject: [PATCH] OCSP: resolve cleanup on connection close

Previously, when a client SSL connection was terminated (typically due to a
timeout) while resolving an OCSP responder, the OCSP context was freed, but
the resolve context was not. This resulted in use-after-free on resolve
completion.

Reported by Leo Lin.

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/nginx/nginx/commit/d2b8d47741820c9fb134c6731ecb40b21f3085b1.patch
---
src/event/ngx_event_openssl_stapling.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c
index a0a8031..231bdec 100644
--- a/src/event/ngx_event_openssl_stapling.c
+++ b/src/event/ngx_event_openssl_stapling.c
@@ -113,6 +113,7 @@ struct ngx_ssl_ocsp_ctx_s {

ngx_resolver_t *resolver;
ngx_msec_t resolver_timeout;
+ ngx_resolver_ctx_t *resolve;

ngx_msec_t timeout;

@@ -1341,6 +1342,10 @@ ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx)
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
"ssl ocsp done");

+ if (ctx->resolve) {
+ ngx_resolve_name_done(ctx->resolve);
+ }
+
if (ctx->peer.connection) {
ngx_close_connection(ctx->peer.connection);
}
@@ -1433,7 +1438,10 @@ ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx)
resolve->data = ctx;
resolve->timeout = ctx->resolver_timeout;

+ ctx->resolve = resolve;
+
if (ngx_resolve_name(resolve) != NGX_OK) {
+ ctx->resolve = NULL;
ngx_ssl_ocsp_error(ctx);
return;
}
@@ -1522,6 +1530,7 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
}

ngx_resolve_name_done(resolve);
+ ctx->resolve = NULL;

ngx_ssl_ocsp_connect(ctx);
return;
@@ -1529,6 +1538,8 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
failed:

ngx_resolve_name_done(resolve);
+ ctx->resolve = NULL;
+
ngx_ssl_ocsp_error(ctx);
}

--
2.45.4

78 changes: 78 additions & 0 deletions SPECS/nginx/CVE-2026-42934.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
From 836d171ed4d51ee0781242d17540223bfc2548fe Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen@gmail.com>
Date: Sun, 12 Apr 2026 07:13:23 +0100
Subject: [PATCH] Charset: fix buffer over-read in recode_from_utf8().

When a multi-byte UTF-8 character was split across 3+ single-byte
buffers, the saved bytes continuation path had two related bugs:

ngx_utf8_decode() was called with the last saved-array index instead
of the byte count, causing it to report "incomplete" even when the
sequence was already complete.

The subsequent ngx_memcpy() used that same index as the copy length,
reading past the input buffer boundary.

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/nginx/nginx/commit/54b7945961b2eaafc480d6b85d9635d0db1c126a.patch
---
.../modules/ngx_http_charset_filter_module.c | 20 ++++++-------------
1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 4829600..edb2db5 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -689,7 +689,6 @@ ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, ngx_buf_t *buf,
u_char c, *p, *src, *dst, *saved, **table;
uint32_t n;
ngx_buf_t *b;
- ngx_uint_t i;
ngx_chain_t *out, *cl, **ll;

src = buf->pos;
@@ -783,18 +782,12 @@ ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, ngx_buf_t *buf,
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0,
"http charset utf saved: %z", ctx->saved_len);

- p = src;
-
- for (i = ctx->saved_len; i < NGX_UTF_LEN; i++) {
- ctx->saved[i] = *p++;
-
- if (p == buf->last) {
- break;
- }
- }
+ len = ngx_min(NGX_UTF_LEN - ctx->saved_len, (size_t) (buf->last - src));
+ ngx_memcpy(&ctx->saved[ctx->saved_len], src, len);
+ len += ctx->saved_len;

saved = ctx->saved;
- n = ngx_utf8_decode(&saved, i);
+ n = ngx_utf8_decode(&saved, len);

c = '\0';

@@ -810,7 +803,7 @@ ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, ngx_buf_t *buf,

/* incomplete UTF-8 symbol */

- if (i < NGX_UTF_LEN) {
+ if (len < NGX_UTF_LEN) {
out = ngx_http_charset_get_buf(pool, ctx);
if (out == NULL) {
return NULL;
@@ -823,8 +816,7 @@ ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, ngx_buf_t *buf,
b->sync = 1;
b->shadow = buf;

- ngx_memcpy(&ctx->saved[ctx->saved_len], src, i);
- ctx->saved_len += i;
+ ctx->saved_len = len;

return out;
}
--
2.45.4

45 changes: 45 additions & 0 deletions SPECS/nginx/CVE-2026-42945.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
From d319f40b492fae26c36a95f70e629e4871e9c381 Mon Sep 17 00:00:00 2001
From: Roman Arutyunyan <arut@nginx.com>
Date: Wed, 22 Apr 2026 09:39:31 +0400
Subject: [PATCH] Rewrite: fixed escaping and possible buffer overrun

The following code resulted in incorrect escaping of $1 and possible
segfault:

location / {
rewrite ^(.*) /new?c=1;
set $myvar $1;
return 200 $myvar;
}

If there were arguments in a rewrite's replacement string, the is_args flag
was set and incorrectly never cleared. This resulted in escaping applied
to any captures evaluated afterwards in set or if. Additionally buffer was
allocated by ngx_http_script_complex_value_code() without escaping expected,
thus this also resulted in buffer overrun and possible segfault.

A similar issue was fixed in 74d939974d43.

Reported by Leo Lin.

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/nginx/nginx/commit/524977e7c534e87e5b55739fa74601c9f1102686.patch
---
src/http/ngx_http_script.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index a2b9f1b..2ea6113 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1202,6 +1202,7 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)

r = e->request;

+ e->is_args = 0;
e->quote = 0;

ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
--
2.45.4

133 changes: 133 additions & 0 deletions SPECS/nginx/CVE-2026-42946.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
From 3704d5a2eb4bd8115bec2a3bf6ac59fb4828331a Mon Sep 17 00:00:00 2001
From: Sergey Kandaurov <pluknet@nginx.com>
Date: Wed, 29 Apr 2026 21:56:51 +0400
Subject: [PATCH 1/2] Upstream: reset parsing state after invalid status line

Previously, it was possible to start parsing headers with a wrong
parsing state after status line was not recognized, as a fallback
used in the scgi and uwsgi modules.

Reported by Leo Lin.
---
src/http/modules/ngx_http_scgi_module.c | 1 +
src/http/modules/ngx_http_uwsgi_module.c | 1 +
2 files changed, 2 insertions(+)

diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 49977b0..0383807 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1029,6 +1029,7 @@ ngx_http_scgi_process_status_line(ngx_http_request_t *r)

if (rc == NGX_ERROR) {
u->process_header = ngx_http_scgi_process_header;
+ r->state = 0;
return ngx_http_scgi_process_header(r);
}

diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index 406018e..57b1bfd 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1266,6 +1266,7 @@ ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)

if (rc == NGX_ERROR) {
u->process_header = ngx_http_uwsgi_process_header;
+ r->state = 0;
return ngx_http_uwsgi_process_header(r);
}

--
2.45.4


From a5dcc31b67bab720a54b3fc46382a64fd447bca6 Mon Sep 17 00:00:00 2001
From: Sergey Kandaurov <pluknet@nginx.com>
Date: Wed, 29 Apr 2026 23:02:20 +0400
Subject: [PATCH 2/2] Upstream: fixed parsing of split status lines

If the first response line was split across reads and it didn't appear
a status line, the portion already processed was lost. To preserve ABI,
the change reuses r->header_name_start for proper backtracking on status
line fallback.

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/nginx/nginx/commit/baef7fdac28e4e1fe26509b50b8d15603393e28e.patch https://github.com/nginx/nginx/commit/39d7d0ba0799fcff6baee52b6525f45739593cfd.patch
---
src/http/modules/ngx_http_proxy_module.c | 5 +++++
src/http/modules/ngx_http_scgi_module.c | 5 +++++
src/http/modules/ngx_http_uwsgi_module.c | 5 +++++
3 files changed, 15 insertions(+)

diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 6861689..44a31e4 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1835,6 +1835,10 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)

u = r->upstream;

+ if (r->state == 0) {
+ r->header_name_start = u->buffer.pos;
+ }
+
rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);

if (rc == NGX_AGAIN) {
@@ -1842,6 +1846,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
}

if (rc == NGX_ERROR) {
+ u->buffer.pos = r->header_name_start;

#if (NGX_HTTP_CACHE)

diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 0383807..7477df3 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1021,6 +1021,10 @@ ngx_http_scgi_process_status_line(ngx_http_request_t *r)

u = r->upstream;

+ if (r->state == 0) {
+ r->header_name_start = u->buffer.pos;
+ }
+
rc = ngx_http_parse_status_line(r, &u->buffer, status);

if (rc == NGX_AGAIN) {
@@ -1029,6 +1033,7 @@ ngx_http_scgi_process_status_line(ngx_http_request_t *r)

if (rc == NGX_ERROR) {
u->process_header = ngx_http_scgi_process_header;
+ u->buffer.pos = r->header_name_start;
r->state = 0;
return ngx_http_scgi_process_header(r);
}
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index 57b1bfd..21b2fc3 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1258,6 +1258,10 @@ ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)

u = r->upstream;

+ if (r->state == 0) {
+ r->header_name_start = u->buffer.pos;
+ }
+
rc = ngx_http_parse_status_line(r, &u->buffer, status);

if (rc == NGX_AGAIN) {
@@ -1266,6 +1270,7 @@ ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)

if (rc == NGX_ERROR) {
u->process_header = ngx_http_uwsgi_process_header;
+ u->buffer.pos = r->header_name_start;
r->state = 0;
return ngx_http_uwsgi_process_header(r);
}
--
2.45.4

Loading
Loading