DragonFlyBSD Kernel Audit
DF-0560 / bttest.c
← back to finding ↓ download raw
/*
 * DF-0560 -- conceptual PoC skeleton for hci_event_command_compl OOB read.
 *
 * This PoC CANNOT run to completion on the audit guest because no BT
 * controller (HW or virtual-HCI) is attached. The path
 *
 *   ubt(4)  ->  ng_hci / hci_recv  ->  hci_event_handler(...)
 *                                      ->  hci_event_command_compl()
 *                                         ->  m_copydata(m, 0, 1, &rp)
 *                                             [m is empty after m_adj]
 *                                             ->  KASSERT(m != NULL) panic
 *
 * is dead code without a BT controller. The skeleton is included to
 * document the trigger that a malicious BT peer (or a virtual-HCI
 * injection tool on a system that has one) would use.
 *
 * Trigger (conceptual): a malicious BT controller sends an HCI event
 * packet of type Command Complete (0x0e) with a 3-byte payload
 * {num_cmd_pkts, opcode_lo, opcode_hi} and NO return params. The
 * kernel's BT stack accepts the 3-byte event (passes the KKASSERT at
 * hci_event.c:299), strips sizeof(hci_command_compl_ep)=3 bytes via
 * m_adj, leaving m_pkthdr.len=0. The unconditional m_copydata at line
 * 313 then reads 1 byte from an empty mbuf chain -> KASSERT panic on
 * INVARIANTS kernels, NULL-deref on others.
 */

#include <stdio.h>

int main(void) {
    fprintf(stderr,
        "[DF-0560] PoC skeleton -- cannot run on guest without BT HW/vhci.\n"
        "Trigger: send a Command Complete HCI event (type=0x04 event=0x0e)\n"
        "with a 3-byte payload {num_cmd_pkts, opcode_lo, opcode_hi} and NO\n"
        "return params, from a BT controller to the kernel BT stack.\n"
        "Effect: panic in m_copydata() at hci_event.c:313 on INVARIANTS\n"
        "kernels; NULL-deref at m_copydata on non-INVARIANTS kernels.\n"
        "Fix: fix.diff adds length check `if (m_pkthdr.len >= sizeof(rp))`\n"
        "around the unconditional m_copydata.\n");
    return 0;
}