DF-0436 — ng_btsocket_hci_raw_filter heap OOB read + security bypass
======================================================================

**Verdict:** NOT REPRODUCED LIVE (latent code bug; module not shipped).

**Confirmed by static trace** at `sys/netgraph7/bluetooth/socket/ng_btsocket_hci_raw.c:669-718`.
The bug is real; it just can't be triggered on the master DEV ISO because the
netgraph7 Bluetooth modules are not shipped in `/boot/kernel/` and there is no
Bluetooth adapter exposed to the guest.

Mechanism
---------
`ng_btsocket_hci_raw_filter()` runs the HCI security filter on every CMD/EVENT
packet an unprivileged PF_BLUETOOTH raw socket tries to send or receive.  The
filter uses two `bitstr_t` arrays inside a kmalloc'd `struct
ng_btsocket_hci_raw_sec_filter`:

    struct ng_btsocket_hci_raw_sec_filter {
        bitstr_t events[0xff / 8];             // 32 bytes   @ offset 0
        bitstr_t commands[0x3f][0x3ff / 8];    // 8064 bytes @ offset 32
    };

The CMD path (line 681-684) does:
    bit_test(commands[NG_HCI_OGF(opcode) - 1], NG_HCI_OCF(opcode) - 1)
where `NG_HCI_OGF(op) = (op>>10)&0x3f` and `NG_HCI_OCF(op) = op&0x3ff`.

With attacker-controlled opcode == 0:
- `commands[0 - 1]` = `commands[-1]` reads 128 bytes BEFORE commands[0],
  i.e. 96 bytes BEFORE the struct's kmalloc allocation.  **Heap OOB read.**
- `bit_test(arr, 0 - 1)` reads `arr[(-1)>>3]` = `arr[-1]`, 1 byte before
  the inner array.  **Heap OOB read.**

The EVENT path (line 703): `event = ...->event - 1` underflows when the
event code is 0, then `bit_test(events, -1)` reads `events[-1]`, 1 byte
before the events array (= 1 byte before the struct allocation).

**Security bypass:** the result of every OOB `bit_test` drives the EPERM
decision.  An attacker who can shape heap state (or just gets lucky with
uninitialized memory) can let normally-restricted HCI commands/events
through the filter.

Why not reproduced
------------------
- `/boot/kernel/` on the master DEV ISO ships NO bluetooth modules.  Only
  USB-HCI drivers (uhci/ehci/xhci/sdhci) are present; netgraph7 Bluetooth
  (ng_btsocket_hci_raw, ng_hci, ng_ubt) is absent.
- `kldload ng_btsocket_hci_raw` / `ng_hci` / `ng_ubt` all return ENOENT.
- No Bluetooth adapter is exposed to the QEMU guest.

The bug is therefore a **latent code defect**: real on any system that
builds + loads the netgraph7 BT stack with a BT adapter, but unreachable on
the master DEV guest.  Classification: not_reproduced (latent), trace-confirmed.

Fix
---
`fix.diff` adds OGF/OCF/event == 0 guards before the array indexing.  With
the fix, opcode 0/0 and event 0 are rejected with EPERM/EINVAL before any
`bit_test` runs.

Notes
-----
- The fix is mechanical (three zero-checks); the `sys/` tree is read-only
  during audit so the diff is generated but not applied.
- If DragonFly ever ships the netgraph7 Bluetooth modules by default, this
  finding becomes live-reproducible as both an OOB read and a security
  bypass for unprivileged PF_BLUETOOTH sockets.
