CVE-2026-19938 in Zephyr
요약
\~에 의해 VulDB • 2026. 10. 13.
블루투스 호스트의 ATT 전송 경로에서 서명 실패 시 소유하지 않는 버퍼를 해제합니다. subsys/bluetooth/host/att.c에 있는 chan_send() 함수는 (그리고 다른 모든 오류 종료 지점도 구현하고 있듯이) 실패 시 호출자가 net_buf의 소유권을 유지한다는 계약을 문서화하고 있습니다. 그러나 BT_ATT_OP_SIGNED_WRITE_CMD 분기에서는 bt_smp_sign()이 오류를 반환할 때 net_buf_unref(buf)을 호출한 후 해당 오류를 호출자에게 반환했습니다. 호출자들은 이 계약에 따라 행동합니다: process_queue()는 k_queue_prepend()로 버퍼를 다시 큐에 넣고, bt_att_chan_send_rsp()은 이를 chan->tx_queue에 되돌리며, bt_att_chan_req_send()는 요청으로 복원하고, att_req_retry()는 참조 카운트를 감소시킵니다. 결과적으로 이미 해제된 버퍼가 재큐되고 나중에 역참조(dereferenced)되어 결국 다시 해제됩니다.
어플리케이션이 암호화되지 않은 연결에서 sign 플래그를 설정하여 bt_gatt_write_without_response_cb()를 호출할 때 ATT Signed Write Command가 생성됩니다. 로컬 CSRK(Connection Signature Resolving Key)가 피어(peer)에 대해 존재하지 않을 경우(-ENOENT), 또는 그 존재 여부가 피어와 협상되는 과정에서(bt_smp_distribute_keys()는 피어의 페어링 키 분배 필드가 서명 키를 요청하고 바인딩이 합의된 경우에만 로컬 CSRK를 저장함) bt_smp_sign()은 실패합니다. 따라서 피어는 CSRK 수락 없이 페어링하거나, No Bonding으로 페어링하거나, 비페어링 상태로 남거나, 링크를 암호화하지 않은 채로 둘 수 있으며, 이로 인해 피해자의 다음 서명된 쓰기 작업이 실패 경로로 진입하게 됩니다. struct net_buf의 node 필드는 ATT TX FIFO용 연결 단어이자 att_pool destroy 콜백인 att_tx_destroy()가 사용하는 deferred-destroy 목록 및 풀 free list를 동시에 나타내므로, mishandled(잘못 처리된) 버퍼는 이러한 목록들을 손상시키고 bt_att_create_pdu()에 의해 새로운 PDU로 재발행될 수 있으며, 이 시점에는 ATT TX 경로에서 여전히 해당 버퍼를 보유하고 있게 됩니다.
동일한 분기에서는 서명 후에만 net_buf_simple_state를 저장했으므로, bt_l2cap_send_pdu() 실패 후 복원된 버퍼는 12옥텟의 서명을 그대로 유지했습니다. 이후 재시도 시 net_buf_add(buf, 12)로 두 번째 서명이 추가되어, bt_att_create_pdu()가 정확히 하나의 서명만 수용하도록 크기를 설정한 풀(buffer pool) 내 버퍼 끝을 넘어쓰게 됩니다(이는 net_buf tailroom 어설션이 컴파일되지 않은 빌드에서 발생합니다).
영향은 블루투스 스택의 호스트 측 메모리 손상입니다: 목록 손실, 두 개의 소유자를 가진 풀된 ATT 버퍼(PDU 내용 전송 오류 또는 연결 해제 시 큐가 비워질 때 double free), 그리고 재시도 경로에서의 제한적 out-of-bounds write(일반적으로 크래시나 어설션 실패로 관찰됨) 등이 있습니다. 노출되려면 deprecated CONFIG_BT_SIGNING이 활성화되어 있고 실제로 서명된 쓰기를 수행하는 어플리케이션이 존재해야 합니다; 이러한 구성에서 트리거링 조건은 원격 피어의 제어 하에 있습니다.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.