flawopen.com/Teardowns/cve-2020-0022-android-bluetooth-hci-heap-overflow

● CVE-2020-0022 · CVSS 8.8 · 高
セキュリティ研究 · FlawOpen

技術解説とコード分析:CVE-2020-0022: Android Fluoride Bluetooth HCI Heap Buffer Overflow Teardown

vulnerabilidade に関する技術的なソースコード解析と堅牢化対策:脆弱性の根本原因と安全な実装パッチの詳細。

💡 わかりやすい解説 (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.

根本原因の分析 (Root Cause)

根本原因は、オープンソースシステムにおける未検証の境界パラメータに起因し、状態の非同期化とセキュリティ制御の迂回を可能にします。

ステップ・バイ・ステップの攻撃フロー

Step 1

攻撃フェーズ:Attacker in Bluetooth Range

技術的な脆弱性悪用メカニズムと実行フローの詳細:The attacker broadcasts crafted ACL packets toward a nearby Android device.

Step 2

攻撃フェーズ:Sending Incomplete First Fragment

技術的な脆弱性悪用メカニズムと実行フローの詳細:The attacker sends an initial L2CAP packet claiming a small total packet length.

Step 3

攻撃フェーズ:Sending Oversized Continuation Packet

技術的な脆弱性悪用メカニズムと実行フローの詳細:The attacker sends a second fragment with an unexpected payload size exceeding the allocation.

Step 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;
}

エンジニアリング&システム堅牢化チェックリスト

参考資料