[하루한줄] CVE-2025-10456 : Zephyr RTOS의 BLE의 검증 미흡으로 인한 DoS
URL
Target
- Zephyr RTOS의 BLE <= v4.1
Explain
CVE-2025-10456은 Zephyr RTOS의 BLE(Bluetooth Low Energy)에서 발생한 DoS 취약점입니다. 해당 취약점은 Bluetooth 프로토콜 스택 상에서 물리계층과 그 상위계층 간의 통신을 지원하는 L2CAP 계층에서 integer overflow를 방지하기 위한 코드로 부터 발생했습니다. 원인이 된 코드는 BLE의 L2CAP 처리 코드에서 발견되었기 때문에 Bluetooth에서는 트리거 되지 않으며 BLE에서만 트리거가 가능합니다.
취약점이 발견된 곳은 L2CAP Flow Control Credit Indication 요청을 처리하는 l2cap.c의 le_credits() 함수 입니다.
static void le_credits(struct bt_l2cap *l2cap, uint8_t ident,
struct net_buf *buf)
{
struct bt_conn *conn = l2cap->chan.chan.conn;
struct bt_l2cap_chan *chan;
struct bt_l2cap_le_credits *ev = (void *)buf->data;
struct bt_l2cap_le_chan *le_chan;
uint16_t credits, cid;
...
cid = sys_le16_to_cpu(ev->cid);
credits = sys_le16_to_cpu(ev->credits);
le_chan = BT_L2CAP_LE_CHAN(chan);
if (atomic_get(&le_chan->tx.credits) + credits > UINT16_MAX) { //[1] trigger point
LOG_ERR("Credits overflow");
bt_l2cap_chan_disconnect(chan); //disconnect when integer overflow
return;
}
코드의 [1]에서 credits는 16비트 필드이며 tx.credits는 atomic_t 이기 때문에 tx.credits+credits의 값이 65,535 이상일 경우 integer overflow이 발생할 수 있기 때문에 UINT16_MAX를 한계값으로 검사하고 있습니다. 이후 해당 채널의 연결을 종료시키기 위해 bt_l2cap_chan_disconnect()를 호출하게 됩니다.
int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan)
{
struct bt_conn *conn = chan->conn;
struct net_buf *buf;
struct bt_l2cap_disconn_req *req;
struct bt_l2cap_le_chan *le_chan;
if (!conn) {
return -ENOTCONN;
}
if (IS_ENABLED(CONFIG_BT_CLASSIC) && //[*]
conn->type == BT_CONN_TYPE_BR) {
return bt_l2cap_br_chan_disconnect(chan);
}
le_chan = BT_L2CAP_LE_CHAN(chan);
LOG_DBG("chan %p scid 0x%04x dcid 0x%04x", chan, le_chan->rx.cid, le_chan->tx.cid);
le_chan->ident = get_ident(); // alloc new ID to channel
buf = l2cap_create_le_sig_pdu(BT_L2CAP_DISCONN_REQ,
le_chan->ident, sizeof(*req));
if (!buf) {
return -ENOMEM;
}
req = net_buf_add(buf, sizeof(*req)); // [2] request packet struct
req->dcid = sys_cpu_to_le16(le_chan->tx.cid);
req->scid = sys_cpu_to_le16(le_chan->rx.cid);
l2cap_chan_send_req(chan, buf, L2CAP_DISC_TIMEOUT); // [3] send disconnect msg
bt_l2cap_chan_set_state(chan, BT_L2CAP_DISCONNECTING);
return 0;
}
이후 해당 함수의 코드 [2]에서 해당 채널의 tx.cid, rx.cid를 req 구조체에 담아 연결 해제를 위한 메시지를 코드의 [3] 함수 호출을 통해 전송합니다.
| 코드의 [*] 부분으로 인해 해당 취약점은 Bluetooth에는 영향을 미치지 않습니다.
static void le_disconn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
struct net_buf *buf)
{
struct bt_conn *conn = l2cap->chan.chan.conn;
struct bt_l2cap_le_chan *chan;
struct bt_l2cap_disconn_rsp *rsp = (void *)buf->data;
uint16_t scid;
if (buf->len < sizeof(*rsp)) {
LOG_ERR("Too small LE disconn rsp packet size");
return;
}
scid = sys_le16_to_cpu(rsp->scid);
LOG_DBG("dcid 0x%04x scid 0x%04x", sys_le16_to_cpu(rsp->dcid), scid);
chan = l2cap_remove_rx_cid(conn, scid);
if (!chan) {
return;
}
bt_l2cap_chan_del(&chan->chan);
}
하지만 이후 request를 처리하는 le_disonn_rsp()에서 cid 값에 대한 검증이 존재하지 않아 고정된 CID 값을 가지는 중요한 서비스들(LE SIGNAL CHANNEL, SMP, ATT …)에 대해 연결해제가 가능해져 DoS 공격이 발생합니다.
Reference
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.