Bug 2480746 (CVE-2026-9256)
| Summary: | CVE-2026-9256 nginx: ngx_http_rewrite_module: code execution and denial of service | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | OSIDB Bzimport <bzimport> |
| Component: | vulnerability | Assignee: | Product Security DevOps Team <prodsec-dev> |
| Status: | NEW --- | QA Contact: | |
| Severity: | high | Docs Contact: | |
| Priority: | high | ||
| Version: | unspecified | CC: | bhg7698, cbrasic, kaycoth, rhel-process-autobot, watson-tool-maintainers |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: |
A flaw was found in the ngx_http_rewrite_module module of NGINX. When a rewrite directive uses a regex pattern with distinct, overlapping Perl-Compatible Regular Expression (PCRE) captures and a replacement string that references multiple such captures in a redirect or arguments context, an unauthenticated attacker can send crafted HTTP requests and cause a heap-based buffer overflow in the worker process, potentially allowing code execution or a denial of service by forcing the process to restart.
|
Story Points: | --- |
| Clone Of: | Environment: | ||
| Last Closed: | Type: | --- | |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | 2481243 | ||
| Bug Blocks: | |||
|
Description
OSIDB Bzimport
2026-05-22 15:01:18 UTC
This issue has been addressed in the following products: Red Hat Enterprise Linux 9 Via RHSA-2026:28212 https://access.redhat.com/errata/RHSA-2026:28212 This issue has been addressed in the following products: Red Hat Enterprise Linux 8 Via RHSA-2026:28921 https://access.redhat.com/errata/RHSA-2026:28921 This issue has been addressed in the following products: Red Hat Enterprise Linux 9 Via RHSA-2026:28973 https://access.redhat.com/errata/RHSA-2026:28973 This issue has been addressed in the following products: Red Hat Enterprise Linux 9 Via RHSA-2026:29151 https://access.redhat.com/errata/RHSA-2026:29151 This issue has been addressed in the following products: Red Hat Enterprise Linux 10 Via RHSA-2026:29874 https://access.redhat.com/errata/RHSA-2026:29874 The RHEL9 build shipped for RHSA-2026:29151 (`nginx-1.26.3-9.module+el9.8.0+24374+c0e15309.1`) has an ABI-breaking regression: any out-of-tree dynamic nginx module segfaults on the first request. It comes from the `max_headers` patch (bundled in the same build, for the HTTP/2 DoS / CVE-2026-49975), which inserts a field into a public struct in `src/http/ngx_http_request.h`: ```diff typedef struct { ngx_list_t headers; + ngx_uint_t count; ngx_table_elt_t *host; ``` `ngx_http_headers_in_t` is embedded by value in `ngx_http_request_t`, so this shifts every subsequent field. A module built against the prior `1.26.3-9` respin reads `r->headers_in.*` at the wrong offsets → `worker process exited on signal 11`. `NGX_MODULE_SIGNATURE` should refuse an incompatible module at load time, but it only encodes struct-affecting *build options*, not source struct changes, so it's byte-identical across both builds — the module loads, then crashes: ```console $ for b in <prior-respin> 24374+c0e15309.1; do rpm2cpio nginx-core-*"$b"*.rpm | cpio --to-stdout -i --quiet ./usr/sbin/nginx \ | strings | grep -m1 -E '^[0-9]+,[0-9]+,[0-9]+,' done 8,4,8,0011111111010111011111111111111111 8,4,8,0011111111010111011111111111111111 # identical, yet ABI differs ``` Two issues: 1. `max_headers` is an nginx 1.27 feature; an ABI-affecting struct change shouldn't land in a z-stream security build. 2. It ships under an unchanged NVR and unchanged module signature, so the safeguard meant to make this fail-load instead lets it segfault under live traffic. Ubuntu hit the identical regression and fixed it in USN-8398-3 (reverted the CVE fix in -2, re-fixed in -3) — https://ubuntu.com/security/CVE-2026-49975#notes Suggested fix: respin dropping the `max_headers` struct change from the 1.26 z-stream, or bump a signature-affecting identifier so mismatched modules are refused at load time. Subject: Regression in nginx-2:1.20.1-28.el9_8.3.alma.1 — workers mass-aborting, Writing connections climbing to worker_connections limit We'd like to report a production regression that appeared after this CVE-2026-9256 fix was backported into the EOL nginx:1.20 module stream on AlmaLinux 9.8. Environment: AlmaLinux 9.8, x86_64 nginx 1.20.1 module stream, upgraded manually 2026-06-29 23:17:37 directly from 2:1.20.1-22.el9_6.3.alma.2 to 2:1.20.1-28.el9_8.3.alma.1 worker_connections 5000; Mixed HTTP/1.1 + HTTP/2 traffic (browsers, mobile app, search bots) Backend via fastcgi_pass to php-fpm over unix sockets (not TCP) Timeline: Manual package upgrade: 2026-06-29 23:17:37 First anomaly in error.log: 2026-06-30 00:00:32 Recurring bursts throughout the night, increasing in frequency (~110 min apart → ~30 min apart by morning) ~09:00–11:00: site effectively unreachable, nginx-status "half-alive" Manual dnf downgrade to 2:1.20.1-28.el9_8.2.alma.1 (the last build without this CVE fix) performed at 11:14 to resolve the incident — the systemd Main process exited, code=killed, status=9/KILL entries around 10:26 and 11:01 were from our own manual restart/kill attempts during this rollback, not an automated action. The downgrade immediately and fully resolved the issue, and it has not recurred since. Symptom in error.log — recurring bursts of dozens of worker PIDs logging aborting in the same second: 2026/06/30 00:00:32 [alert] 842391#842391: aborting 2026/06/30 00:00:32 [alert] 842393#842393: aborting ... (13+ more PIDs, same timestamp) followed by open socket #N left in connection M from the same/neighboring PIDs (workers not closing sockets gracefully before terminating), and continuously: [alert] NNNNN#NNNNN: 5000 worker_connections are not enough (~198,000 occurrences that day, matching nginx-status Writing climbing from single digits to 5,000–10,000 in a sawtooth pattern). Ruled out: No RPS/traffic increase around the incident (confirmed via monitoring — RPS flat, php-fpm RPS unchanged) No cron/systemd-timer-triggered reload/restart in the affected windows No OOM-kill events correlating with the abort bursts No targeted attack pattern in access logs — the ~1,200 slow (>5s) HTTP/2 requests that day were spread across many unrelated IPs/user-agents with normal, fully-delivered response bodies, not the small-payload/near-zero-byte pattern of a Slowloris/HPACK-bomb exploit Backend is unix-socket based, ruling out ephemeral port exhaustion Working hypothesis: the mass, synchronous aborting bursts (no external trigger) look consistent with an internal timeout/shutdown mechanism related to this fix's Slowloris/HTTP2-hold mitigation misfiring on legitimate slow HTTP/2 transfers (large responses, mobile clients on poor connections) rather than an actual attack — causing workers to self-terminate under normal load. Downgrading to the pre-patch build resolved it with no config changes. We're currently pinned to 2:1.20.1-28.el9_8.2.alma.1 (without this fix) to keep production stable. Happy to provide full config/logs if useful. Solarpepper, why did you flag needsinfo from me? Unclear what you are looking for. |