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