# DF-5171 — vcdstrategy() panics on BUF_CMD_FLUSH / BUF_CMD_FREEBLKS

**vkernel virtual CD-ROM driver** — `sys/dev/virtual/vkernel/cdrom/vcd.c`

## What

`vcdstrategy()` (vcd.c:136-177) handles only `BUF_CMD_READ` and
`BUF_CMD_WRITE`; every other buffer command hits:

```c
default:
        panic("vcd: bad b_cmd %d", bp->b_cmd);   /* vcd.c:165 */
```

The vdisk sibling was reworked in 2016 and handles `BUF_CMD_FLUSH`
(vdisk.c:332-337, `fsync()` on the backing file); **vcd never got that
treatment**. Two in-tree producers deliver non-R/W bios to any block
device:

* **HAMMER** — `hammer_io_flush_sync()` (sys/vfs/hammer/hammer_io.c:1985-2007)
  issues a `BUF_CMD_FLUSH` bio (`b_bcount=0`, `bio_offset=0`) through
  `vn_strategy(volume->devvp)` on every mount-time recovery and every
  flusher cycle (`hammer_io_wait_all(..., 1)` from
  hammer_flusher.c:784,910 and hammer_recover.c:1438,1461,1465).
* **FFS with `mount -o trim`** — `ffs_blkfree()` (sys/vfs/ufs/ffs_alloc.c:1668-1705)
  issues `BUF_CMD_FREEBLKS`. (Killed during verification: the MNT_TRIM
  gate tests `ip->i_devvp->v_mount` — the *devfs* mount — so the TRIM
  branch is dead code in this tree; see VERDICT.md §4.)

## Impact

A guest **root** inside the vkernel that mounts a HAMMER filesystem on a
vcd-backed volume (or would use FFS TRIM on one) **panics the vkernel
instantly** — inside the `mount(2)` syscall. The vkernel is a userspace
process on the host, so this is a crash/DoS of the vkernel instance, not
of the host kernel and not a privilege boundary on the host.

**Currently gated behind DF-1031**: on HEAD, `init_disk(cdFile, NULL, …, VKD_CD)`
passes `diskFlags == NULL` and dereferences `diskFlags[i]`
(sys/platform/vkernel64/platform/init.c:487-489 + init_disk body), so the
`-c` option kills the vkernel before any vcd device can exist. The moment
that crash is fixed (a two-line fix), this bug is live: the PoC boots a
vkernel with that enabler applied and panics on the first HAMMER flush.

## Verified on the guest (2026-09-30)

* **Baseline:** `panic: vcd: bad b_cmd 5` at uptime 3s, inside `mount(2)`
  — run.log:45-46, backtrace included. (That build also carried a
  temporary per-bio kprintf which recorded the fatal bio verbatim:
  `VCDDBG: bio cmd=5 off=0 bcount=0 dev=vcd0` — exactly the
  `hammer_io_flush_sync` shape.)
* **Fix validated:** with `fix.diff` (BUF_CMD_FLUSH → `fsync(sc->fd)`,
  other commands → complete instead of panic) the same PoC prints
  `mount(hammer) returned OK` and `RESULT: no-panic (STILL ALIVE after
  15s)` — fix_run.log:39-40 — and HAMMER reports `mounted clean`.

## Files

* `vcd_flush_poc.c` — decisive PoC (HAMMER route; static PID1 binary).
* `vcd_trim_poc.c` — the FFS-TRIM route explored first (kept as the
  document of why it is dead: ffs_alloc.c:1673).
* `odcat.c`, `guest_prep.sh`, `build.sh`, `run.sh` — harness.
* `run.log` / `fix_run.log` / `panic.txt` — baseline panic, patched run.
* `build.log` / `fix_build.log`, `env.txt` — build output, guest env.
* `fix.diff` — the validated fix (git-apply-able against vcd.c).
