# DF-0031 — PoC

`pipe_leak.c` — `pipe->open_count` underflow on `pipe_create` partial failure
leaks kernel KVA + pipe struct (memory-pressure amplification DoS).

## The bug

`pipe_create` (`sys/kern/sys_pipe.c`): `*pipep = pipe` (`:433`) is set before
the `pipespace()` calls (`:434`/`:437`), and `open_count = 2` (`:445`) only
after both succeed. If `pipespace(&bufferB)` fails (`vm_map_find` ENOMEM on
`kernel_map`), `pipe_create` returns with `open_count` still 0. `kern_pipe`'s
error path (`:287-288`) then calls `pipeclose()` twice; each `pipeclose`
(`:1272`) does `atomic_fetchadd_int(&open_count, -1) == 1` to gate the free.
With `open_count = 0` the sequence underflows `0 → 0xFFFFFFFF → 0xFFFFFFFE`,
never `== 1`, so the pipe struct + `bufferA`'s KVA are leaked permanently and
`open_count` is corrupted.

## Reachability

Unprivileged. Each open pipe holds ~`2*pipe_size` of `kernel_map` KVA; holding
many pushes `kernel_map` toward exhaustion, after which new `pipe_create`
calls hit the second-`pipespace` failure and leak further — self-amplifying.
Pure availability (KVA/struct leak); no confidentiality/integrity impact.

## Build & run (unprivileged, disposable VM)

```
cc -o pipe_leak findings/poc/DF-0031/pipe_leak.c
./pipe_leak
```

## Expected output (bug present)

Cumulative `kernel_map` free-space shrinkage and pipe-zone struct growth
(observed via `vmstat -z` / `vmstat -m`) that never reclaims, worsening the
OOM. No standalone panic.
