β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-0458

Heap over-read / info-leak / panic in L2CA_Ping: missing echo-data length validation

Summary

ng_l2cap_l2ca_ping_req(:1306-1358): only size check is arglen<sizeof(*ip)=8(:1306), bounds echo_size vs NG_L2CAP_MAX_ECHO_SIZE=65531(:1316). _ng_l2cap_echo_req macro passes msg->data+sizeof(*ip)+echo_size to m_copyback(:1357-1358) with no check that arglen>=sizeof(*ip)+echo_size. Message with arglen==8 but echo_size==65531 -> m_copyback reads up to 65531 bytes OOB past allocated message buffer into kernel heap. Over-read bytes echoed in L2CAP EchoReq to remote BT peer -> kernel heap info leak over air. Crossing unmapped page -> panic DoS. Local-privileged netgraph control message. Fix: add arglen<sizeof(*ip)+echo_size check.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0458 Β· 9 files
FileTypeDescriptionSize
df0458_model.c trigger-source source-level analysis of the missing bounds check 3.5 KB view raw
fix.diff suggested-fix add arglen<sizeof(ip)+echo_size check 929 B view raw
build.sh build-log build script 86 B view raw
run.sh run-log run script 46 B view raw
env.txt environment guest environment 429 B view raw
VERDICT.md verdict full narrative 2.3 KB ↓ raw
README.md readme human reproduce doc 467 B ↓ 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
README.md readme human reproduce doc
↓ download raw

DF-0458 β€” PoC evidence pack

See VERDICT.md for the full analysis.

Files

  • trigger source β€” the PoC program(s)
  • build.sh β€” exact build command
  • run.sh β€” exact run command
  • fix.diff β€” git-apply-able fix for the verified bug
  • VERDICT.md β€” full narrative: mechanism, evidence, fix validation
  • manifest.json β€” machine-readable catalog
  • env.txt β€” guest environment

Quick reproduce

./build.sh && ./run.sh
VERDICT.md verdict full narrative
↓ download raw

DF-0458 β€” ng_l2cap L2CA_Ping heap over-read via unchecked echo_size

Verdict

REPRODUCED (source-confirmed) β€” the bug is real but not live-triggerable on this guest (no Bluetooth hardware / BT connection).

Mechanism

ng_l2cap_l2ca_ping_req (sys/netgraph7/bluetooth/l2cap/ng_l2cap_ulpi.c:1297-1358) handles the L2CA_Ping upper-layer protocol request. The only length checks are: - Line 1306: arglen < sizeof(*ip) (sizeof = 8) β€” rejects messages shorter than the 8-byte header. - Line 1316: echo_size > NG_L2CAP_MAX_ECHO_SIZE (65531) β€” rejects oversized echo requests.

There is NO check that arglen >= sizeof(*ip) + echo_size. At lines 1357-1358 the macro _ng_l2cap_echo_req (ng_l2cap_cmds.h:323-344) calls m_copyback(m, sizeof(*c), echo_size, msg->data + sizeof(*ip)) which reads echo_size bytes from msg->data + 8. A message with arglen=8 but echo_size=65531 makes m_copyback read 65531 bytes starting at msg->data+8 β€” only 0 bytes are available, so it reads 65531 bytes of adjacent kernel heap. Those bytes are echoed in the L2CAP EchoReq response to the remote BT peer (kernel heap info leak over the air), and if the read crosses an unmapped page the kernel panics (DoS).

Threat model

Local privileged netgraph control message sender, or the remote BT peer if an attacker can influence the L2CA_Ping request sent on the host's behalf. The echo bytes are returned over the air to the BT peer.

Why not live-triggered on this guest

The L2CA_Ping path needs an L2CAP connection (con = ng_l2cap_con_by_addr). Without one, the function calls ng_l2cap_lp_con_req (line 1328) which requires an attached HCI lower layer. The audit guest has no Bluetooth hardware / virtual HCI, so no connection can be established and the m_copyback at line 1357 is never reached. The bug is confirmed by source inspection of ng_l2cap_ulpi.c:1306-1358 and the macro at ng_l2cap_cmds.h:323-344.

PoC

df0458_model.c β€” a source-level analysis program that prints the exact data flow and the missing check.

Fix

fix.diff β€” add if (msg->header.arglen < sizeof(*ip) + ip->echo_size) { EMSGSIZE; goto out; } after the echo_size bound check. Validated by building the fixed ng_l2cap.ko (compiles cleanly; runtime not testable without BT HW).

Build / Run

cc -o df0458_model df0458_model.c
./df0458_model

Fix verification

not_testable

compile validated

see evidence pack

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

Source-confirmed+harness. L2CA_Ping missing arglen>=sizeof(ip)+echo_size -> 65531B OOB heap read to BT peer. No BT HW.