]> git.kaiwu.me - nginx.git/commitdiff
Upstream: fix integer underflow in charset parsing
authorDavid Korczynski <david@adalogics.com>
Wed, 4 Mar 2026 09:27:45 +0000 (01:27 -0800)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Mon, 6 Apr 2026 10:07:18 +0000 (14:07 +0400)
The issue described below was only reproducible prior to
https://github.com/nginx/nginx/commit/7924a4ec6cb35291ea60a5f2a70ac0a034d94ff7

When parsing the `charset` parameter in the `Content-Type` header within
`ngx_http_upstream_copy_content_type`, an input such as `charset="`
resulted in an integer underflow.

In this scenario, both `p` and `last` point to the position immediately
following the opening quote. The logic to strip a trailing quote checked
`*(last - 1)` without verifying that `last > p`. This caused `last` to
be decremented to point to the opening quote itself, making `last < p`.

The subsequent length calculation `r->headers_out.charset.len = last - p`
resulted in -1, which wrapped to `SIZE_MAX` as `len` is a `size_t`. This
invalid length was later passed to `ngx_cpymem` in `ngx_http_header_filter`,
leading to an out-of-bounds memory access (detected as
`negative-size-param` by AddressSanitizer).

The fix ensures `last > p` before attempting to strip a trailing quote,
correctly resulting in a zero-length charset for malformed input.

The oss-fuzz payload that triggers this issue holds multiple 103 status
lines, and it's a sequence of 2 of those Content-Type headers that
trigger the ASAN report.

Co-authored-by: CodeMender <codemender-patching@google.com>
Fixes: https://issues.oss-fuzz.com/issues/486561029
Signed-off-by: David Korczynski <david@adalogics.com>
src/http/ngx_http_upstream.c

index c84defaa953dbca6fc6cf1f9bd1f8dd33469d971..918323d9bbaea257a598efd75112d397169f56c1 100644 (file)
@@ -5652,7 +5652,7 @@ ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
 
         last = h->value.data + h->value.len;
 
-        if (*(last - 1) == '"') {
+        if (last > p && *(last - 1) == '"') {
             last--;
         }