CVE-2024-0044 / Zero-Click Bluetooth

CVE-2024-0044: Android Fluoride Bluetooth HCI Heap Buffer Overflow Teardown

How an unchecked fragmentation boundary mismatch in system/bt/stack/l2cap enabled zero-click remote code execution over Bluetooth.

💡 身近な例えで分かる解説 (ELI5)

Imagine a post office that accepts letters in numbered pieces (Part 1 of 2, Part 2 of 2). An attacker sends Part 1 stating 'the whole letter is 50 words'. The clerk prepares a tiny envelope. Then the attacker sends Part 2 containing 5,000 words! The clerk shoves the words in, bursting the envelope and scattering private documents all over the floor.

中核となる概念とサブシステム用語

Fluoride Bluetooth Stack
The open-source C/C++ Bluetooth protocol stack used in Android, handling L2CAP, SDP, and RFCOMM.
HCI (Host Controller Interface)
The protocol layer communicating between the software Bluetooth stack and the hardware radio chip.
L2CAP (Logical Link Control and Adaptation Protocol)
The protocol responsible for segmenting and reassembling network packets across Bluetooth links.
Heap Buffer Overflow
Writing packet payload data past the allocated boundaries of a heap chunk.

ステップ別エクスプロイト実行メカニズム

Step 1

1. Attacker in Bluetooth Range

The attacker broadcasts crafted ACL packets toward a nearby Android device.

Step 2

2. Sending Incomplete First Fragment

The attacker sends an initial L2CAP packet claiming a small total packet length.

Step 3

3. Sending Oversized Continuation Packet

The attacker sends a second fragment with an unexpected payload size exceeding the allocation.

Step 4

4. Heap Corruption in com.android.bluetooth

The reassembly loop overwrites adjacent heap chunks, executing code inside the Bluetooth daemon.

ソースコード比較:致命的バグ vs 安全な修正

日常的な開発者が直感的に理解できる高級言語コードで提示(バイナリやアセンブリ不使用)。

未修正の脆弱なコード
// VULNERABLE: system/bt/stack/l2cap/l2c_main.cc
void l2c_rcv_acl_data(BT_HDR *p_msg) {
    tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
    
    // ROOT CAUSE:
    // Does not verify that accumulated fragment lengths stay within allocated buffer!
    uint8_t *p_dest = p_lcb->p_rx_msg->data + p_lcb->p_rx_msg->offset;
    
    // Copies fragment without boundary checking!
    memcpy(p_dest, p_msg->data, p_msg->len);
    p_lcb->p_rx_msg->offset += p_msg->len;
}
修正済みの安全なコード
// SECURE: system/bt/stack/l2cap/l2c_main.cc patch
void l2c_rcv_acl_data(BT_HDR *p_msg) {
    tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(handle);
    
    // 1. Calculate remaining capacity in allocated reassembly buffer
    size_t remaining_capacity = p_lcb->p_rx_msg->total_len - p_lcb->p_rx_msg->offset;
    
    // 2. Reject fragment if incoming length exceeds remaining capacity
    if (p_msg->len > remaining_capacity) {
        L2CAP_TRACE_ERROR("L2CAP packet overflow: len %d exceeds remaining %zu", 
                          p_msg->len, remaining_capacity);
        osi_free(p_lcb->p_rx_msg);
        p_lcb->p_rx_msg = nullptr;
        return; // Abort cleanly
    }
    
    uint8_t *p_dest = p_lcb->p_rx_msg->data + p_lcb->p_rx_msg->offset;
    memcpy(p_dest, p_msg->data, p_msg->len);
    p_lcb->p_rx_msg->offset += p_msg->len;
}

開発現場向けシステム堅牢化チェックリスト

← セキュリティディレクトリ一覧 すべてのセキュリティ更新情報 →