⬢ DragonFlyBSD Kernel Audit
DF-5760 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5760",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "Reproduced deterministically with a KLD rig compiling the verbatim production rfcomm_session.c/rfcomm_dlc.c/rfcomm_upper.c against a stubbed L2CAP layer: one PN command with a responder-direction DLCI (7 = channel 3, our direction on a responder session) is accepted by the production recv_mcc_pn -> rfcomm_dlc_newconn path (no direction check, channel-only matching), fabricating a DLC+socket child in the local stacks own DLCI space; every subsequent local rfcomm_connect() to that channel returns EBUSY (rfcomm_upper.c:181-182) until the session dies. Sweeping 30 channels locks the local RFCOMM client out of every server channel (28/29 in run.log; the 29th is blocked by the DF-5762 mask bug). recv_sabm() has the exact missing check (rfcomm_session.c:738-742). Guest stays up: pure validation/logic bug, remote-peer-triggerable DoS plus rogue half-open DLC/socket allocation.",
  "exploit_chain": "Bluetooth-adjacent peer with an established RFCOMM session to the victim service: (1) send PN command with DLCI = MKDLCI(local-direction, ch) for each channel 1..30 -> each creates a rogue DLC via the listening sockets newconn (socket allocation) stuck in WAIT_CONNECT; (2) any local application connect() to those channels now gets EBUSY forever; (3) rogue DLCs linger until session teardown. No memory corruption; ceiling is permanent local-outbound lockout + resource poisoning.",
  "evidence": "run.log: POISON-CONFIRMED: peer-planted DLCI 7 exists on session (state 2), LOCAL-CONNECT: rfcomm_connect(ch 3) -> 16 (EBUSY = 16) <== locked out by peer, POISON-SWEEP: 28/29 poisoned channels refuse local connect with EBUSY, RESULT: PEER CAN LOCK THE LOCAL RFCOMM CLIENT OUT OF ALL CHANNELS; run.fix.log: poison rejected (DLCI 7 state -1), connect -> 0 accepted, newconn calls: 2; setup.log md5s prove verbatim production sources.",
  "kernel_refs": [
    "sys/netbt/rfcomm_dlc.c:72",
    "sys/netbt/rfcomm_dlc.c:88",
    "sys/netbt/rfcomm_dlc.c:92-111",
    "sys/netbt/rfcomm_dlc.c:128-140",
    "sys/netbt/rfcomm_session.c:1322-1331",
    "sys/netbt/rfcomm_session.c:738-742",
    "sys/netbt/rfcomm_upper.c:180-182"
  ],
  "poc_changes": "Adapted the DF-5733 rig (l2cap_stub + inject helpers) to a listener scenario: stub l2cap_sockaddr returns BDADDR_ANY so 30 listeners share one listening session (first iterations fixed 0x11 bdaddr exhausted the stub channel table and crashed in harness code - fixed); listener newconn callback returns fresh rfcomm_attachd child DLCs (sonewconn stand-in); added per-channel PN sweep, fresh probe DLC per channel, listener-identity tags (upper = channel number), and a MASK-CHECK probe shared with DF-5762.",
  "attempts": 4,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 2700,
  "guest_dirty": 0,
  "build_cmd": "cd /root/df5760 && sh build.sh   (copies verbatim /usr/src/sys/netbt sources, KLD make)",
  "run_cmd": "kldload /root/df5760/rfcomm_pn_harness.ko && sysctl hw.rfcomm_pn_fire=1   (reboot required between runs: MOD_UNLOAD is EBUSY)",
  "code_hash": "137c459cd205977dfe37c2d74b48fe42bfc8a242f0989ef27c9ae28946626894",
  "notes": "Baseline + fix-validated in the same session with byte-identical injected frames. The DF-5762 mask bug surfaced inside this rigs sweep (ch16 DM / shifted listener matches) and is filed separately. Rig-internal stub crash on iteration 1 was a harness bug (documented in VERDICT.md), not a production finding.",
  "recommended_fix": "Add the direction-bit validation to rfcomm_session_recv_mcc_pn()s PN-command path, mirroring rfcomm_session_recv_sabm() (see fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "fix.diff (direction check in recv_mcc_pn, DM on violation) applied to the guests /usr/src/sys/netbt copy; rig rebuilt from the patched verbatim sources; same harness and identical frames: PN(DLCI 7) answered with DM, no DLC created (newconn calls: 2), local rfcomm_connect(ch 3) -> 0 (accepted, previously EBUSY), sweep poison fully rejected, guest alive.",
  "fix_evidence": "run.fix.log lines: DUP-CHANNEL: ... peer-planted DLCI 7 (state -1), LOCAL-CONNECT: rfcomm_connect(ch 3) -> 0 (EBUSY = 16) (unexpected), POISON-SWEEP: 1/29 (the 1 is ch4s own baseline DLC); uptime captured in transcript; same-run MASK-CHECK also validates the DF-5762 mask fix."
}