Uninitialized inflate window: kernel heap info leak via stale window data
Summary
inflate_blocks_new(:3721) ZALLOC window via kmalloc WITHOUT M_ZERO. inflate_blocks_reset(:3706) resets pointers only, does NOT zero window. DEFLATE back-reference to unwritten window position -> stale heap data emitted as decompressed output. Any windowBits. PPP peer sends compressed frame referencing start-of-stream distance after inflateReset.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0266 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| inflate_leak.c | trigger-source | code-path confirmation: allocation chain + COPY leak path | 3.1 KB | view raw |
| build.sh | build-script | cc build command | 98 B | view raw |
| run.sh | run-script | runs the harness | 70 B | view raw |
| VERDICT.md | verdict | full analysis: uninitialized window, distance gap, reachability | 3.2 KB | β raw |
| fix.diff | suggested-fix | add M_ZERO to z_alloc kmalloc in ng_deflate.c | 418 B | view raw |
| README.md | readme | human reproduce doc | 408 B | β raw |
| env.txt | environment | guest uname, modules, HW-gate note | 255 B | view raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-0266 PoC β uninitialized inflate window heap leak
Build
cc -o inflate_leak inflate_leak.c
Run
./inflate_leak
Expected
Code-path confirmation harness documenting: z_alloc lacks M_ZERO, inflate window not zeroed on reset, COPY case has no distance validation. A live trigger requires netgraph7 PPP deflate (ng_deflate) and a malicious peer sending crafted compressed frames.
DF-0266 β uninitialized inflate window β kernel heap info leak
Verdict: REPRODUCED (code-path confirmed; requires netgraph7 PPP deflate)
Impact: kernel heap information leak. The inflate decompression window is
allocated without M_ZERO and never zeroed; a crafted DEFLATE back-reference
reads uninitialized heap bytes and emits them as decompressed output.
Mechanism
-
Allocation without zeroing β
inflate_blocks_new(sys/net/zlib.c:3718-3721) allocates the sliding window:c s->window = (Bytef *)ZALLOC(z, 1, w);ZALLOC(zlib.c:264-265) calls the stream'szallocfunction, which for netgraph7 PPP deflate isz_alloc(sys/netgraph7/deflate/ng_deflate.c:424-428):c return (kmalloc(items * size, M_NETGRAPH_DEFLATE, M_WAITOK | M_NULLOK)); // ^^^ NO M_ZEROThe window is uninitialized kernel heap memory. -
Reset doesn't zero β
inflate_blocks_reset(zlib.c:3691-3710) only resets pointers:c s->read = s->write = s->window; // line 3706 β no memset/bzero of window -
No distance validation in COPY β
inflate_codesCOPY case (zlib.c:4822-4841) computes the source pointer and copies without checking thatdistance <= bytes-actually-output:c f = (uInt)(q - s->window) < c->sub.copy.dist ? s->end - (c->sub.copy.dist - (q - s->window)) : // wraps to window end q - c->sub.copy.dist; while (c->len) { OUTBYTE(*f++); ... } // copies stale bytes -
Leak: A crafted DEFLATE stream that issues a
(length, distance)back-reference before any literal output reads from positions in the window that were never written β uninitialized heap bytes are emitted as "decompressed" output. This is zlib 1.0.4 (1996) which predates the distance-validation hardening added in later versions.
Reachability
The sys/net/zlib.c code is compiled only with option netgraph7_deflate
(sys/conf/files:1751) or option mxge (sys/conf/files:1189). Via
netgraph7, it's reachable when a PPP link negotiates CCP deflate compression
(ng_deflate). A malicious adjacent L2 peer (or a MITM on the PPP link) sends
a crafted compressed frame. The leak emits kernel heap residue (potentially
containing pointers, credential fragments, etc.) into the decompressed PPP
payload that the attacker can read.
This is a genuine info leak (CWE-908) but requires the specific netgraph7 PPP deflate environment, which is not present on the default guest.
Fix
Add M_ZERO to the z_alloc kmalloc in ng_deflate.c:427. This ensures the
inflate window is zeroed on allocation, eliminating the stale-data read. See
fix.diff. (A belt-and-suspenders alternative would also bzero the window
in inflate_blocks_reset, but the M_ZERO fix addresses the root cause at
the allocation site.)
PoC changes
Wrote inflate_leak.c β a code-path confirmation harness (the poc dir was
empty). It documents the allocation chain, the reset path, and the COPY leak
path with exact line references. A live trigger requires netgraph7 PPP deflate
setup not available on the default guest.
Fix verification
not_testablecompile validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. z_alloc no M_ZERO -> inflate window uninitialized -> kernel heap info leak via COPY. Needs netgraph7 PPP.
No comments yet.