# DF-4754 VERDICT — REPRODUCED (panic; hostile-device OOB read + wild-pointer primitive)

## Bottom line

Reproduced on the DragonFly 6.5-DEVELOPMENT QEMU guest (X86_64_GENERIC,
2026-07-02 build). A kld-module harness compiles the **real, unmodified**
`/usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c` (the exact file
the finding is filed against) and drives `ena_com_rx_pkt()` with a
synthesized RX completion ring containing precisely what a compromised
host would DMA: one cdesc with PHASE|LAST set, `length=0x4141`,
`req_id=0xFFFF` against `q_depth=1024`.

## Baseline run (vulnerable) — run.log / panic.txt

1. TX contrast: `ena_com_tx_comp_req_id_get(req_id=0xffff)` → `rc=22
   (EINVAL)` — REJECTED by the bounds check at ena_eth_com.c:614.
2. RX path: `ena_com_rx_pkt` → `rc=0, descs=1`, and
   `ena_bufs[0].req_id=0xffff` — the device-controlled req_id is
   propagated to the driver with **no validation** (ena_eth_com.c:540).
3. Driver consumer replication (the exact arithmetic of ena.c:1459):
   `rx_buffer_info = 0xfffff8011bce0000` (1024 entries, 65536 bytes,
   allocated like ena.c:736);
   `&rx_buffer_info[0xffff] = 0xfffff8011c0dffc0` — **4031 KB past the
   end of the ring**.
4. Performing the exact next dereference the driver makes (ena.c:1462,
   `mbuf = rx_info->mbuf`):
   `Fatal trap 12: page fault while in kernel mode`,
   `fault virtual address = 0xfffff8011c0dffc0`,
   `supervisor read data, page not present`,
   `Stopped at df4754_run+0x2e1: movq (%rbx),%rsi` — guest dies in DDB.

That is the OOB-read primitive: with heap memory mapped at the OOB offset
(which a groomed/normal kernel heap often has — it depends on what lies
4 MB past a 64 KB kmem allocation), the driver instead obtains a *foreign
kernel-memory-derived* `struct mbuf *`, then writes through it
(`m_flags |= M_PKTHDR`, `m_pkthdr.len = <device-chosen len>`,
`m_pkthdr.rcvif = ifp`, hash store) and hands the "packet" to if_input —
kernel memory disclosure into the network stack plus semi-controlled
wild-pointer writes. In this harness run the offset happened to be
unmapped, converting the primitive into an immediate kernel panic.

## Why no uid=0 attempt

The attacker in this threat model is the **host** (compromised
hypervisor / buggy PF-equivalent device). The host already owns guest
memory, so guest-internal privilege escalation is not the prize; the
finding is guest-hardening against device-side memory corruption. The
in-guest primitive is real and demonstrated (OOB index → OOB read →
panic); pushing it to controlled guest-memory corruption only matters
for a *sandboxed-device* threat model this port does not have.

## Fix validation — fix.diff / fix_build.log / fix_run.log

`fix.diff` adds the missing check inside the copy loop of
`ena_com_rx_pkt()`, mirroring the TX-side check at line 614 (this also
matches the check upstream FreeBSD later added to this function):

    if (unlikely(cdesc->req_id >= io_cq->q_depth))
        return ENA_COM_INVAL;

Applied inside the guest's /usr/src (`patch -p1`, hunk at line 536),
module rebuilt (compiles the patched /usr/src file — see fix_build.log),
exact same PoC re-run (fix_run.log):

- baseline: `rc=0`, req_id=0xffff propagated, index +4031 KB OOB,
  **Fatal trap 12 panic**.
- patched:  `rc=22 (EINVAL)`, `descs=0`, `req_id=0x0000 rejected`,
  in-bounds index, **no panic, guest stays up** (`vm.sh status` = up).

Scoping note: validation was performed at module level against the real
ena_eth_com.c source file (both baseline and patched builds compile the
same guest /usr/src file); a full kernel rebuild was not needed because
the audited code ships verbatim inside the harness module, and the
in-kernel driver path cannot be exercised without ENA hardware.

## Post-run state

Guest reset to the clean-source snapshot (`vm.sh reset with-src`) after
both runs; module unloaded/reverted with the snapshot. guest_dirty = 0.

## Kernel references

- sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:536-542  (missing check — root cause)
- sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:614       (TX-side check that proves the contract)
- sys/dev/virtual/amazon/ena/ena.c:1459,1491                 (OOB consumer)
- sys/dev/virtual/amazon/ena/ena.c:736                       (array sized ring_size)
- sys/dev/virtual/amazon/ena/ena.c:700-709                   (validate_rx_req_id exists but is only used on the kernel-owned refill path, ena.c:1011)

## 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.
