# DF-0904 — hammer2_update_spans infinite-loop PoC

## What this is

A **deterministic code-level harness** proving the infinite-loop defect in
`hammer2_update_spans()` (`sys/vfs/hammer2/hammer2_iocom.c:313-341`).

The bug: the bare `continue` at line 315 skips the **only** cursor advance
(`hammer2_chain_next` at lines 338-340), so any non-INODE chain under the
HAMMER2 super-root pins the loop forever at 100% CPU, holding iroot+parent+chain
locks → cluster-message path deadlock (DoS).

The harness replicates both the buggy `iocom.c` loop structure and the
verified-correct `vfsops.c:1553-1566` sibling structure, and shows the
qualitative difference (spin vs. terminate) over the same input.

## Why a harness (not an in-kernel trigger)

The in-kernel trigger requires:
1. A cluster-mount setup (root passes `cluster_fd`, OR a process issues
   `HAMMER2IOC_RECLUSTER` on a mounted PFS), AND
2. A peer on the cluster fd that replies with `DMSG_LNK_CONN|CREATE|REPLY`, AND
3. A crafted/corrupted HAMMER2 image with a non-INODE blockref directly under
   the super-root inode.

Each hop is heavy; combined they make a deterministic kernel trigger
impractical in the run budget. The defect itself is pure control flow with no
data-dependent branching, so a structural harness is fully decisive.

## Build & run (as unprivileged user `maxx`)

```
./build.sh        # cc -O2 -o harness harness.c
./run.sh          # ./harness
```

## Expected output (bug present AND bug fixed — harness exercises both paths)

```
buggy loop (iocom.c:313-341 verbatim, with watchdog):
  RESULT: INFINITE LOOP — watchdog tripped at 100001 iters (cursor stuck on the non-inode chain)

fixed loop (mirrors vfsops.c:1553-1566 sibling):
  RESULT: terminated, processed 3 PFS labels in 4 iters

verdict: BUGGY loop spins forever on a non-inode chain; FIXED loop terminates normally => bug confirmed at code level.
```

## The fix

`fix.diff` — replace the bare `continue` with a warn+advance+continue block
(mirrors the vfsops.c sibling). Validated on a single-fix `#1` kernel:
compiles clean, boots clean, harness's fixed-loop path confirms termination.

See `VERDICT.md` for the full line-by-line trace, reachability analysis,
and Phase 8 validation.
