
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-85091 is a heap buffer overflow vulnerability in the gz_vacate() function of zlib, affecting versions 1.3.1.2 through 1.3.2. The flaw is triggered when non-blocking gzwrite() operations stall (returning EAGAIN) and the application subsequently calls gzprintf() or gzvprintf() after gzclearerr(), causing an unchecked memmove() to write up to ~983 KB beyond the 16,384-byte internal input buffer boundary. It was published on September 3, 2026, with a Microsoft patch advisory added on September 5, 2026. The vulnerability carries a CVSS v3.1 score of 7.4 (High) and a CVSS v4.0 score of 8.3 (High) (GitHub Advisory, Microsoft).
The root cause (CWE-787: Out-of-bounds Write) lies in gz_write()'s "large path," which sets strm->next_in directly to the caller's external buffer for zero-copy deflation. When gz_comp() returns -1 due to EAGAIN on a non-blocking descriptor, gz_write() exits without resetting strm->next_in or strm->avail_in, leaving a stale external pointer. gzclearerr() only resets state->err and state->msg — it does not touch strm->next_in or strm->avail_in. When gzprintf() is subsequently called, it invokes gz_vacate(), which contains a guard comparing pointers from two unrelated malloc allocations using a relational operator — undefined behavior per C11 §6.5.8p5. On glibc, the guard typically evaluates false, and memmove(state->in, strm->next_in, strm->avail_in) fires with avail_in up to 983,041 bytes against a 16,384-byte destination buffer. The vulnerability was introduced in zlib 1.3.1.2 with the addition of gz_vacate(); zlib 1.3.1 exhibits a lower-severity 1-byte null write via the same root cause. Full PoC source code (pipe-based and socket-based) is publicly available (GitHub Gist, zlib source).
Successful exploitation can crash the affected process (guaranteed on glibc due to the unconditional memmove firing) and may enable arbitrary code execution, as the ~983 KB write is both length- and content-controlled by the attacker. Integrity is impacted because 983,041 bytes of heap memory beyond state->in are overwritten with caller-controlled data. Confidentiality may also be affected because crash dumps expose heap contents adjacent to state->in, which may include deflate internal state or sensitive application data. The vulnerability has no direct lateral movement primitive, but process compromise in a network-facing service could serve as an initial foothold (GitHub Gist).
A public proof-of-concept (both pipe-based and socket-based) is available as a GitHub Gist, and the NVD SSVC assessment classifies exploitation status as "poc." The socket-based PoC demonstrates that the stall condition is network-reachable — a remote peer that stops reading from a TCP socket creates the same EAGAIN condition. Three preconditions must hold simultaneously: the application must use a non-blocking file descriptor for gzip output, the stalling gzwrite() call must carry at least state->size bytes, and gzprintf() must be called after gzclearerr() on the same handle before the descriptor drains, making exploitation complexity high. The EPSS score is 0.0044 (approximately 0.44%), and there is no evidence of in-the-wild exploitation or CISA KEV catalog listing as of the report date (GitHub Gist, GitHub Advisory).
gzwrite() on a non-blocking socket).gz_comp() inside gzwrite() to return EAGAIN, triggering the stale-pointer condition.gzclearerr(): Many applications call gzclearerr() to recover from a write stall before retrying. This resets state->err but leaves strm->next_in pointing to the external caller buffer and strm->avail_in holding the unconsumed byte count.gzprintf() or gzvprintf(): The application's retry logic calls gzprintf() (e.g., to append a chunk boundary). This invokes gz_vacate(), which evaluates the undefined-behavior pointer guard — on glibc, the guard evaluates false.memmove(state->in, strm->next_in, strm->avail_in) executes with avail_in up to 983,041 bytes against a 16,384-byte state->in buffer, overwriting ~966 KB of heap with caller-controlled data, crashing the process or potentially enabling code execution (GitHub Gist).gz_vacate, gzvprintf, or gzprintf as shown in stack traces.gzwrite.c:393 (gz_vacate), gzwrite.c:438 (gzvprintf), or gzwrite.c:492 (gzprintf); ASAN output showing heap-buffer-overflow WRITE of size 983041./var/crash/, potentially containing sensitive heap data (GitHub Gist).Upgrade zlib to a version newer than 1.3.2 (e.g., 1.3.2.1 or later, as the zlib repository shows active development past 1.3.2). Apply security updates provided by your OS vendor or the official zlib project for any bundled or statically linked copies. As a short-term workaround, avoid calling gzprintf() or gzvprintf() after gzclearerr() on non-blocking gzip file handles, or avoid using non-blocking descriptors with the gz* API until patched. Audit all applications that statically link zlib 1.3.1.2–1.3.2 and rebuild them against the patched version (GitHub Advisory, Microsoft, zlib repo).
Microsoft included CVE-2026-85091 in its September 2026 Patch Tuesday advisory cycle, which was covered by BleepingComputer as part of a broader roundup fixing 966 flaws. The Yocto Project security mailing list flagged the vulnerability for embedded Linux maintainers. The VulnCheck advisory provided detailed technical analysis corroborating the researcher's findings. Community discussion on Bluesky and aggregator sites (VulDB, CVEFeed) noted the availability of PoC code shortly after disclosure.
Fix availability across major Linux distributions and their releases.
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."