# VERDICT — DF-3820

**Status: inconclusive** (device-gated: no AAC controller on the audit
guest; nothing can execute these paths without adapter DMA/MMIO).
**Source-level confidence: certain** — every site is a plain, unguarded
array-index-to-pointer computation on adapter-supplied data.

## The five sites

| # | site | source of index | target object | bound that should hold |
|---|------|-----------------|--------------|------------------------|
| 1 | aac.c:853 (`aac_new_intr`) | `AAC_GET_OUTB_QUEUE()` MMIO | `sc->aac_commands[]` (total_fibs ≤ 512/256) | `index >> 2 < sc->total_fibs` |
| 2 | aac.c:1118 (`aac_complete`) | `fib->Header.SenderData` (DMA) | `sc->aac_commands[]` | `SenderData < sc->total_fibs` |
| 3 | aac.c:2221-2223 (`aac_dequeue_fib` AIF) | `aq_fib_addr` (adapter-written queue entry) | `sc->aac_common->ac_fibs[8]` | `fib_index < AAC_ADAPTER_FIBS` |
| 4 | aac.c:2238-2240 (`aac_dequeue_fib` resp) | same | `sc->aac_commands[]` | `fib_index >> 2 < total_fibs` |
| 5 | aac.c:3771-3772 (`aac_get_bus_info`) | `BusCount` (LCT/DMA-derived reply) | stack `businfo.BusValid[10]`, `InitiatorBusId[10]` | `BusCount ≤ AAC_SCSI_MAX_PORTS` |

Not one of them validates.  The driver comment at aac.c:2232-2237 even
acknowledges the value "was originally provided by the driver" — but a
malicious or buggy adapter is free to return anything.

## Why these matter even though they are device-gated

Modern threat models treat PCIe devices as untrusted once firmware
compromise or a Thunderbolt-style attach is in play; DragonFly's own
hardening push (IOMMU-less boards included) treats device-driven OOB as a
finding class.  Sites 1-4 hand the attacker a *fully controlled* fake
`struct aac_command` location (via the 32-bit index scaling) which the
completion machinery then writes through (`aac_remove_busy` →
`TAILQ_REMOVE` unlink writes; `callout_stop`; indirect call
`cm->cm_complete(cm)`), i.e. arbitrary-write primitives, not just panics.

The upstream FreeBSD ancestor has the same pattern; this finding is filed
as shared-hardening.

## Guest evidence

The audit guest has no AAC hardware whatsoever:

- `ls /dev/aacd0` → ENOENT; `pciconf -l | grep -c "vendor=0x(1044|9005|9004|1028)"` → 0
  (copied as ../DF-3819/env.txt, identical run).
- aac is compiled into X86_64_GENERIC but never attaches.

No kernel path can be driven without the card ⇒ `inconclusive`, honest
per the audit's status set.

## Fix

`fix.diff` adds the five missing bounds checks (print + drop/break), each
against the correct limit: `sc->total_fibs` (×3), `AAC_ADAPTER_FIBS`,
`AAC_SCSI_MAX_PORTS`.

## Fix validation

`not_testable` — same hardware precondition as the baseline.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
