# DF-2429 — Divide-by-zero in bt(4) XPT_CALC_GEOMETRY from device-fed block_size

## Verdict: REPRODUCED (kernel panic via the production handler)

The QEMU guest has no BusLogic MultiMaster HBA, so the compiled-in bt(4)
driver (`bt` at X86_64_GENERIC:102; `btaction`/`btdone`/`btreset`/
`bttimeout` present in `/boot/kernel/kernel`) never attaches.  The rig
(`dfbt_rig.c`) stands in only for the missing PCI hardware:

- resolves the REAL static production handlers from the running kernel
  image (no KASLR; host-side `nm` + runtime prologue byte-verification of
  all six handlers before any dispatch);
- registers a REAL `cam_sim` whose `sim_action` IS production `btaction`,
  over a fabricated post-attach softc (real lockmgr lock, real bus_dma
  tags, real DMA memory for CCBs/mailboxes);
- drives the REAL CAM XPT layer with `xpt_action()` on real
  `xpt_alloc_ccb`'d CCBs;
- scripts a 4-byte virtual register file behind `bt->port`
  (`X86_64_BUS_SPACE_MEM` tag → plain volatile memory, see
  sys/cpu/x86_64/include/bus_dma.h:134-142).

## Build

    ./push_rig.sh        # scp sources, build kld + ctl, kldload, prime
    # then verify prologue magic words against the expected constants

## Run

    sh run.sh            # = run_df2429.sh

## Expected output

1. `calcgeom 0 4194304` **survives**: heads=0 spt=0 cyl=0 status=0x1 —
   the CAM layer filters `block_size == 0` at cam_xpt.c:3063-3071, so
   the ==0 variant NEVER reaches bt.c (partial false-positive in the
   original finding; documented in VERDICT.md).
2. `calcgeom 2097152 4194304` (block_size = 2 MiB > 1 MiB): the filter
   passes (both fields non-zero), production `btaction`'s
   XPT_CALC_GEOMETRY case computes `(1024*1024)/block_size == 0` and
   then divides `volume_size` by it (bt.c:1157-1158) →
   **Fatal trap 18: integer divide fault**, `Stopped at btaction+0x4ff:
   divq %rsi,%eax` (see panic.txt).

## Threat model

`ccg->block_size` is fed unvalidated from SCSI READ CAPACITY
(scsi_da.c:1831 `scsi_4btoul(rdcap->length)` → scsi_da.c:2302
`ccg->block_size = dp->secsize`), so a lying/hostile SCSI target behind
a real bt(4) HBA reporting secsize > 1 MiB panics the kernel (local DoS
from device-supplied data).
