β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-0266

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0266 Β· 9 files
FileTypeDescriptionSize
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
README.md readme human reproduce doc
↓ download 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.

VERDICT.md verdict full analysis: uninitialized window, distance gap, reachability
↓ download raw

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

  1. 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's zalloc function, which for netgraph7 PPP deflate is z_alloc (sys/netgraph7/deflate/ng_deflate.c:424-428): c return (kmalloc(items * size, M_NETGRAPH_DEFLATE, M_WAITOK | M_NULLOK)); // ^^^ NO M_ZERO The window is uninitialized kernel heap memory.

  2. 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

  3. No distance validation in COPY β€” inflate_codes COPY case (zlib.c:4822-4841) computes the source pointer and copies without checking that distance <= 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

  4. 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_testable

compile 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.