# DF-2069 — REPRODUCED (source-confirmed, HW-gated) + FIX VALIDATED

## Verdict

**REPRODUCED via source-only trace.** The CHS-path divide-by-zero in
`ata_serverworks_tf_write` is real: the function reads `current_heads`/
`current_sectors` from IDENTIFY without the `current_heads &&
current_sectors` guard that the *sibling* geometry-adoption code in
`ata-disk.c` applies. The bug is HW-gated on this guest (no ServerWorks
PCI ATA controller present), so there is no runtime PoC.

## Mechanism (path:line)

`ata_serverworks_tf_write` is wired into the channel's `hw.tf_write`
vector at `sys/dev/disk/nata/chipsets/ata-serverworks.c:158`. Its CHS
branch:

* `sys/dev/disk/nata/chipsets/ata-serverworks.c:219` (original)
  ```c
  if (atadev->param.atavalid & ATA_FLAG_54_58) {
      heads = atadev->param.current_heads;
      sectors = atadev->param.current_sectors;
  }
  else { ... }
  ATA_IDX_OUTW(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1);   /* :228 */
  ATA_IDX_OUTW(ch, ATA_CYL_LSB, (request->u.ata.lba / (sectors*heads))); /* :230 */
  ATA_IDX_OUTW(ch, ATA_CYL_MSB, (request->u.ata.lba / (sectors*heads)) >> 8); /* :232 */
  ATA_IDX_OUTW(ch, ATA_DRIVE, ... ((request->u.ata.lba%(sectors*heads))/sectors)&0xf); /* :234 */
  ```

If `ATA_FLAG_54_58` is set in `atavalid` but `current_sectors == 0`
(observed on misbehaving / emulated ATA devices that set the validity
bit but report zero geometry), `sectors` is `0` and every CHS expression
divides by zero → kernel divide-by-zero trap → panic.

The sibling geometry-adoption code refuses the bad geometry:

* `sys/dev/disk/nata/ata-disk.c:469-470`
  ```c
  if ((atadev->param.atavalid & ATA_FLAG_54_58) &&
      atadev->param.current_heads && atadev->param.current_sectors) {
      adp->heads = atadev->param.current_heads;
      ...
  ```

`ata-disk.c` correctly adds the `current_heads && current_sectors`
clause; `ata-serverworks.c` did not. The result is that
`ata-disk.c:ad_invalidate()` falls through to the safe `param.heads`/
`param.sectors` branch but the very next I/O request that calls
`tf_write` panics the kernel.

## Reachability / impact ceiling

**HW-gated.** Requires a ServerWorks ATA PCI controller (ROSB4/CSB5/CSB6/
HT1000/Frodo/K2 family — `ata-serverworks.c:47-59`) with a disk whose
IDENTIFY data sets `ATA_FLAG_54_58` but reports `current_sectors == 0`.
The audit guest is virtio-only and has no such controller. If reachable,
the impact is **panic / local DoS** (CVSS A:H). No memory-corruption
primitive is derivable from a divide-by-zero trap.

## Fix

`fix.diff`:

1. Adds the `&& current_heads && current_sectors` clause to the if at
   line 219 so the safe `param.heads/param.sectors` fallback is used
   when the current_* fields are bogus (matches `ata-disk.c:469-470`).
2. Adds a final defensive `if (heads == 0 || sectors == 0) {
   request->result = EIO; return; }` immediately before the divisions,
   covering the (theoretical) case where the fallback `param.sectors`
   is also zero. The ata-queue caller (`ata-queue.c:181,208,348,420`)
   honors `request->result` and fails the I/O cleanly.

Supersedes the finding markdown's recommendation.

## Phase-8 build validation

Combined kernel + modules build (DF-2068 / DF-2069 / DF-2070 / DF-2071 /
DF-2072) on DragonFly 6.5-DEVELOPMENT #0 baseline:

* `=== NK_DONE rc=0 ===` (2026-07-25 11:31:20 UTC)
* `0` `error:` lines in the full 35,696-line build log
* `ata-serverworks.c` is part of the in-kernel `nata` driver; the
  patched TU compiled clean with the kernel's default
  `-Wall ... -Wno-pointer-sign -Werror` flags and linked into the
  kernel binary (`ata_serverworks_tf_read` / `ata_serverworks_tf_write`
  confirmed present via `nm` on `kernel.debug`).

The default kernel build IS a `-Werror` build; see `fix_build.log` and
`env.txt`.

## Reproduce

```
./build.sh    # rebuilds the patched kernel (rc=0 with -Werror)
./run.sh      # source-only confirmation; no runtime PoC (HW-gated)
```
