CVE-2024-43770 AI-generated analysis
platform/packages/modules/Bluetooth, system/stack/gatt (GATT server, ATT request processing)
Adds early returns in four GATT server request handlers in system/stack/gatt/gatt_sr.cc when gatt_tcb_get_payload_size_tx() returns 0 (channel already closed), so response buffers are no longer allocated with a zero payload size and written past their end.
Root cause
In gatt_sr.cc, the functions gatts_process_primary_service_req, gatts_process_find_info, gatts_process_read_by_type_req and gatts_process_read_req get the ATT payload size from gatt_tcb_get_payload_size_tx(tcb, cid). They use it right away to size a response buffer (sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET) without checking that it is positive. Per the commit message, in exceptional cases the channel is already closed when the handler runs, so the function returns 0, which leads to an OOB write in later processing. One example from the context: gatt_build_primary_service_rsp writes the opcode and length byte at p = (p_msg + 1) + L2CAP_MIN_OFFSET before its 'p_msg->len + p_msg->offset > payload_size' check (lines 555-568). With a zero-sized payload area, p points at the end of the allocation, so these writes land outside it.
How the fix works
- gatt_sr.cc:gatts_process_primary_service_req: after 'uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);' the fix adds 'if (payload_size == 0) return;' before msg_len is computed and osi_calloc is called.
- gatt_sr.cc:gatts_process_find_info: the same zero check is added after payload_size is obtained and before buf_len is computed.
- gatt_sr.cc:gatts_process_read_by_type_req: the same zero check is added before msg_len, osi_calloc and the pointer setup.
- gatt_sr.cc:gatts_process_read_req: the same zero check is added at function entry, before buf_len is computed.
- All four hunks are independent, additive validity checks (21 insertions, no deletions). Neither gatt_tcb_get_payload_size_tx nor the response builders are changed.
Completeness
- Covers the four request handlers named in the diff. Each now returns before any allocation or write when payload_size is 0.
- gatt_build_primary_service_rsp (context line 540) still calls gatt_tcb_get_payload_size_tx on its own and has no zero check of its own. When it is called from gatts_process_primary_service_req, the new check covers it. The material does not show whether it has other callers.
- The response builders are not made robust against a small payload_size by themselves. The fix relies on the early return in the four handlers.
- The material does not show whether gatt_tcb_get_payload_size_tx has other users in gatt_sr.cc or elsewhere (for example write or indication paths).
Behavior changes
- When the channel's payload size is 0 (closed channel), the four handlers now return silently: no response buffer is allocated and neither a response nor an ATT error response is sent for that request.
- No change in behavior when payload_size is non-zero.
Per major
- Android 14: Same fix: commit c7468e64bb5e in android-security-14.0.0_r15 adds four zero checks after gatt_tcb_get_payload_size_tx. 8/8 patched lines are present at android-security-14.0.0_r29.
- Android 15: Adapted fix: commit 339ea2fc1905 in android-security-15.0.0_r3 has the same four hunks, but on this branch the helper is called gatt_tcb_get_payload_size (no _tx suffix). 8/8 lines are present at android-security-15.0.0_r17.
- Android 16: Not affected (not listed by the bulletin). 5/8 lines of the patched region are present at android-security-16.0.0_r8; the material does not show the exact code form.
- Android 17: Not affected (not listed by the bulletin). 5/8 lines of the patched region are present at android-security-17.0.0_r1; the material does not show the exact code form.
Unknowns
- The exact sequence by which the channel closes while a request is still being processed (the commit only says 'exceptional cases').
- Whether gatt_tcb_get_payload_size_tx has other call sites in gatt_sr.cc or other GATT files that use the result to size buffers. The material only shows the four fixed sites plus gatt_build_primary_service_rsp.
- Whether gatt_build_primary_service_rsp has callers other than gatts_process_primary_service_req.
- Whether the builders used by the other three handlers write before checking payload_size.
- What the Android 16/17 code looks like at the patched sites (only a 5/8 line match is reported).