nginx: fix CVE-2026-27654

As per the advisory[1] mentioned in NVD[2], version 1.28.3 contains the fix.
Backport the commit[3] from 1.28.3 changelog matching the description.

[1] https://my.f5.com/manage/s/article/K000160382
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-27654
[3] https://github.com/nginx/nginx/commit/a1d18284e0a173c4ef2b28425535d0f640ae0a82

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
Ankur Tyagi
2026-04-09 23:22:06 +12:00
committed by Anuj Mittal
parent 958cca3987
commit 24459e3f5c
2 changed files with 82 additions and 0 deletions
@@ -0,0 +1,81 @@
From be39034fa93a4d44b52de9b7a463754eda56e712 Mon Sep 17 00:00:00 2001
From: Roman Arutyunyan <arut@nginx.com>
Date: Mon, 16 Mar 2026 20:13:03 +0400
Subject: [PATCH] Dav: destination length validation for COPY and MOVE.
Previously, when alias was used in a location with Dav COPY or MOVE
enabled, and the destination URI was shorter than the alias, integer
underflow could happen in ngx_http_map_uri_to_path(), which could
result in heap buffer overwrite, followed by a possible segfault.
With some implementations of memcpy(), the segfault could be avoided
and the overwrite could result in a change of the source or destination
file names to be outside of the location root.
Reported by Calif.io in collaboration with Claude and Anthropic Research.
(cherry picked from commit a1d18284e0a173c4ef2b28425535d0f640ae0a82)
CVE: CVE-2026-27654
Upstream-Status: Backport [https://github.com/nginx/nginx/commit/a1d18284e0a173c4ef2b28425535d0f640ae0a82]
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
src/http/modules/ngx_http_dav_module.c | 39 +++++++++++++++++---------
1 file changed, 26 insertions(+), 13 deletions(-)
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index cfb98929e..4619b139a 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -535,19 +535,20 @@ ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf)
static ngx_int_t
ngx_http_dav_copy_move_handler(ngx_http_request_t *r)
{
- u_char *p, *host, *last, ch;
- size_t len, root;
- ngx_err_t err;
- ngx_int_t rc, depth;
- ngx_uint_t overwrite, slash, dir, flags;
- ngx_str_t path, uri, duri, args;
- ngx_tree_ctx_t tree;
- ngx_copy_file_t cf;
- ngx_file_info_t fi;
- ngx_table_elt_t *dest, *over;
- ngx_ext_rename_file_t ext;
- ngx_http_dav_copy_ctx_t copy;
- ngx_http_dav_loc_conf_t *dlcf;
+ u_char *p, *host, *last, ch;
+ size_t len, root;
+ ngx_err_t err;
+ ngx_int_t rc, depth;
+ ngx_uint_t overwrite, slash, dir, flags;
+ ngx_str_t path, uri, duri, args;
+ ngx_tree_ctx_t tree;
+ ngx_copy_file_t cf;
+ ngx_file_info_t fi;
+ ngx_table_elt_t *dest, *over;
+ ngx_ext_rename_file_t ext;
+ ngx_http_dav_copy_ctx_t copy;
+ ngx_http_dav_loc_conf_t *dlcf;
+ ngx_http_core_loc_conf_t *clcf;
if (r->headers_in.content_length_n > 0 || r->headers_in.chunked) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -644,6 +645,18 @@ destination_done:
return NGX_HTTP_CONFLICT;
}
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->alias
+ && clcf->alias != NGX_MAX_SIZE_T_VALUE
+ && duri.len < clcf->alias)
+ {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "client sent invalid \"Destination\" header: \"%V\"",
+ &dest->value);
+ return NGX_HTTP_BAD_REQUEST;
+ }
+
depth = ngx_http_dav_depth(r, NGX_HTTP_DAV_INFINITY_DEPTH);
if (depth != NGX_HTTP_DAV_INFINITY_DEPTH) {
@@ -6,6 +6,7 @@ SRC_URI:append = " \
file://CVE-2023-44487.patch \
file://CVE-2026-28755.patch \
file://CVE-2026-27651.patch \
file://CVE-2026-27654.patch \
"
SRC_URI[sha256sum] = "77a2541637b92a621e3ee76776c8b7b40cf6d707e69ba53a940283e30ff2f55d"