# DF-3167 — hammer_reblock_data() OOB kernel write via unvalidated on-disk
`leaf->data_len` + misaligned >16KB allocation

## What this proves

A single forged B-Tree leaf element (direntry record) in a HAMMER1 image
causes `hammer reblock` (root-run maintenance command, `HAMMERIOC_REBLOCK`
ioctl) to write attacker-controlled data past the end of a 64KB kernel
buffer:

```
hammer_reblock_data()                     sys/vfs/hammer/hammer_reblock.c:487
    bcopy(cursor->data, ndata, elm->leaf.data_len);   /* 65536 bytes */
```

* `elm->leaf.data_len` comes straight from disk (only a KKASSERT guards it,
  `hammer_btree.c:736`).
* `hammer_alloc_data()` (hammer_ondisk.c:1634) allocates `data_len` bytes;
  for records with `data_len > HAMMER_BUFSIZE` the blockmap allocator only
  enforces the **big-block** boundary (`hammer_blockmap.c:183-188`), so the
  allocation may land at a non-16KB-aligned cursor offset `xoff` (the META
  zone cursor is *naturally* misaligned — dirents/inodes pack at 16-byte
  granularity).
* The destination buffer is `getblk(DOALIGN16K(data_len))` bytes and
  `ndata = buffer->ondisk + xoff` (`hammer_ondisk.c:1114-1143, 715-722`).
* The copy writes `[xoff, xoff + data_len)` into a `DOALIGN16K(data_len)`-
  sized buffer → **`xoff` bytes (up to 16368) past the end**, with fully
  attacker-controlled content (the old record data, CRC-checked against the
  forged `data_crc`).

Observed on the guest: `xoff = 0x1390` (4912 bytes) past the buffer end →
`Fatal trap 12: page fault while in kernel mode, supervisor write data,
page not present` in `memmove+0x10a` (the bcopy). Guest dead at `db>`.

The mirror-symmetric variant (misaligned **source** `data_offset`) is an
OOB **read** of adjacent kernel buffer-cache memory, CRC'd and persisted
into the record's new data block (kernel memory disclosure to the image).

## Preconditions / threat model

Same family as DF-3033 / DF-3076 / DF-3148: the mount+reblock operator is
root (`caps_priv_check(cred, SYSCAP_NOVFS_IOCTL)` at hammer_ioctl.c:72);
the attacker is the **provider of the filesystem image** (untrusted disk /
backup / VM image the admin mounts and maintains). No unprivileged trigger.

## Reproduce

Everything runs inside the QEMU guest as root (see VERDICT.md for the
environment):

```
./build.sh          # compile patch_leaf (stage 2 forger)
./run.sh            # stage 1 (mkimage.sh: build legit fs image)
                    # stage 2 (patch_leaf: forge the dirent leaf)
                    # stage 3 (trigger.sh: mount + hammer reblock)
```

Expected (vulnerable kernel): console/syslog shows

```
hammer_blockmap_getfree: a000000022000000 -> 7340032
hammer_reblock_helper: D 7340032/0
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0xfffff8005272a000
fault code = supervisor write data, page not present
Stopped at memmove+0x10a: repe movsq (%rsi),%es:(%rdi)
```

and the guest hangs at the `db>` prompt (see panic.txt, run.log).

Expected (kernel with fix.diff): no trap; `hammer reblock` completes
normally; guest stays up.

## Artifacts

* `mkimage.sh`      — stage 1: vnconfig + newfs_hammer + payload files
* `patch_leaf.c`    — stage 2: self-validating leaf forger (CRC32C/CRC32)
* `trigger.sh`      — stage 3: mount, enable vfs.hammer.debug_general=0x4000,
                      run `hammer reblock /mnt`
* `build.sh`,`run.sh`, `build.log`, `run.log`, `panic.txt`, `env.txt`
* `fix.diff`        — verified fix (hammer_reblock.c + hammer_blockmap.c)
