Heap OOB read + security-filter bypass via OGF=0/event=0: negative bitstr index into ng_btsocket_hci_raw_sec_filter
Summary
ng_btsocket_hci_raw_filter(:669-718): CMD_PKT uses bit_test(commands[OGF(opcode)-1], OCF(opcode)-1)(:679-684). OGF=0 -> commands[-1] = 128 bytes before commands[0] = 96 bytes before struct start -> heap OOB read. OCF=0 -> bit_test(..,-1) -> name[-1>>3] = 1 byte before array. EVENT_PKT: event=mtod->event-1(:703) then bit_test(events,event)(:709). event code 0 -> bit index -1 -> events[-1] 1 byte before struct. bitstr_t unsigned char bit_test=name[bit>>3]&(1<<(bit&7)). Trigger: unpriv local user sendto() 3-byte HCI cmd OGF=0 (attach:936 no priv required). Heap OOB read leaks slab metadata + when tested bit set -> filter bypass -> unpriv socket injects privileged HCI commands.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0436 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| trace_analysis.c | trigger-source | static trace artifact (no runnable PoC; module not shipped) | 4.2 KB | view raw |
| build.sh | build-script | compiles the trace artifact | 203 B | view raw |
| run.sh | run-script | prints the not-reproducible explanation | 573 B | view raw |
| VERDICT.md | verdict | trace-confirmed latent bug analysis | 2.9 KB | β raw |
| fix.diff | suggested-fix | OGF/OCF/event==0 guards in ng_btsocket_hci_raw_filter | 1.7 KB | view raw |
| env.txt | environment | guest uname, kldload ENOENT evidence | 1.1 KB | view raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
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_ubtall 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.
Fix verification
not_testablecompile validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. ng_btsocket_hci_raw OGF=0/event=0 negative array index OOB read + security bypass. No BT HW/modules shipped.
No comments yet.