Android security tags, read closely by Lightrion

CVE-2024-43096 AI-generated analysis

platform/packages/modules/Bluetooth, GATT server (system/stack/gatt) and EATT (system/stack/eatt)

AI-generated: written from the bulletin and the fixing diffs by claude-fable-5-1, then checked against the code by claude-opus-5-5 (8 corrections). Verify against the commit before relying on it.

Adds an mtu == 0 rejection at the top of build_read_multi_rsp in system/stack/gatt/gatt_sr.cc and clamps the EATT channel tx MTU to at least EATT_MIN_MTU_MPS in EattChannel::EattChannelSetTxMTU, so the Read Multiple response buffer is never allocated with zero payload room before the opcode byte is written.

Root cause

build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) allocates a BT_HDR buffer of size sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu, sets p to (p_buf + 1) + L2CAP_MIN_OFFSET, and unconditionally writes the response opcode (GATT_RSP_READ_MULTI or GATT_RSP_READ_MULTI_VAR) at *p++ and sets p_buf->len = 1. With mtu == 0 the allocation has no payload bytes, so the opcode write lands one byte past the end of the osi_calloc'd buffer. Nothing validated mtu before the write. On the EATT side, EattChannelSetTxMTU only applied an upper clamp (std::min with EATT_MAX_TX_MTU), so a tx_mtu_ of 0 (or anything below the EATT minimum) could be stored. The code context shows it is called at eatt.h line 70, apparently from the EattChannel constructor. Per index search, it is also called with the peer-provided p_cfg->mtu in eatt_impl.h eatt_l2cap_reconfig_completed when !is_local_cfg.

How the fix works

Completeness

Behavior changes

Per major

Unknowns

Back to January 2025 · Findings