# DF-0543 — VERDICT

**Verdict:** NOT REPRODUCED at runtime (source-CONFIRMED real OOB-read; the
vulnerable code is dead/opt-in on the default guest).
**Impact:** none on a default install (latent; conditional on
`netgraph7_bluetooth` + BT hardware).
**Confidence:** likely (bug confirmed by source trace; not runtime-observed
because the module is not compiled/shipped/loadable on the default guest).

## Mechanism (source-confirmed)

1. `ng_hci_process_event()` (`ng_hci_evnt.c:86`) pulls the 3-byte HCI header,
   logs `hdr->length` (`:100`) but does not enforce it, dispatches on
   `hdr->event` (`:106`).
2. `NG_HCI_EVENT_NUM_COMPL_PKTS` → `num_compl_pkts()` (`:171`,`:878`).
3. `num_compl_pkts()` pulls only `sizeof(ng_hci_num_compl_pkts_ep)` = 1 byte
   (`num_con_handles`) (`:884`), `m_adj`s it (`:889`), then loops
   `for (; ep->num_con_handles > 0; ...)` (`:891`) with **no length guard**.
4. Each iteration consumes 4 bytes: `m_copydata(sizeof(h)=2)`+`m_adj(2)`
   (`:893-894`) and `m_copydata(sizeof(p)=2)`+`m_adj(2)` (`:898-899`). `h`,`p`
   are `u_int16_t` (`:882`).
5. When `num_con_handles` exceeds the chain's data, `m_adj` drains the chain to
   NULL; the next `m_copydata()` walks `m = m->m_next` to NULL and trips
   `KASSERT(m != NULL, "%s: length > size of mbuf chain")` at
   `sys/kern/uipc_mbuf.c:1687` → **panic (INVARIANTS/GENERIC)**; non-INVARIANTS
   ⇒ NULL `m->m_len` deref ⇒ page-fault panic. No copyout path (parsed values
   only update an in-kernel connection counter), so this is panic/DoS, not a
   direct info leak.

Same root cause as DF-0542 (`ng_hci_process_event` never validates
`hdr->length`). The bug is real and not a false positive.

## Why NOT reproduced at runtime

Identical to DF-0542: netgraph7 bluetooth is `optional netgraph7_bluetooth`,
absent from `X86_64_GENERIC`, no `.ko` ships, standalone `ng_hci.ko` builds but
`kldload` fails ("depends on ng_bluetooth - not available"), and reaching
`num_compl_pkts()` requires a real HCI event from a BT controller. ⇒ dead/
unreachable at runtime on this guest AND no userspace harness can exercise it
without building the netgraph7 BT stack (root) + BT hardware — a valid hard
blocker for live reproduction.

## Fix-validation (fix.diff)

`fix.diff` bounds the loop by remaining `event->m_pkthdr.len`:
```c
for (; ep->num_con_handles > 0 &&
       event->m_pkthdr.len >= (sizeof(h) + sizeof(p));
     ep->num_con_handles --) { ... }
```
- git-apply clean; compiles (patched `ng_hci.ko` build rc=0, `build_hci.log`).
- `fix_status`: **not_testable** (runtime). Validated apply + compile; traced
  to close the over-read.

## PoC changes

Created the evidence pack from scratch (empty on handoff): `README.md`, this
`VERDICT.md`, `env.txt`, `build_result.txt`, `build_hci.log`, `fix.diff`,
`manifest.json`.

## Recommended fix (summary)

In `sys/netgraph7/bluetooth/hci/ng_hci_evnt.c`, bound `num_compl_pkts()`'s
loop by the remaining mbuf length (stop when `event->m_pkthdr.len <
sizeof(h)+sizeof(p)`, 4 bytes/entry). (Matches the finding's "clamp
num_con_handles to m_pkthdr.len/4" proposal.)
