CVE-2024-43771 AI-generated analysis
platform/packages/modules/Bluetooth, GATT server (system/stack/gatt/gatt_sr.cc)
Adds early-return checks for a zero payload size (returned by gatt_tcb_get_payload_size_tx when the channel is already closed) in four ATT server request handlers in system/stack/gatt/gatt_sr.cc. This stops undersized response buffers from being allocated and written out of bounds.
Root cause
In gatt_sr.cc, gatts_process_primary_service_req, gatts_process_find_info, gatts_process_read_by_type_req and gatts_process_read_req call gatt_tcb_get_payload_size_tx(tcb, cid). They use the result directly to size the response buffer (sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET) and to bound later writes. The commit message says that in exceptional cases the channel can already be closed when the function is called, so the returned payload size is 0. The handlers did not check for this, so later processing caused an OOB write.
How the fix works
- system/stack/gatt/gatt_sr.cc:gatts_process_primary_service_req: after payload_size is computed via gatt_tcb_get_payload_size_tx, the function returns immediately if payload_size == 0. This happens before osi_calloc of p_msg and before the response is built.
- system/stack/gatt/gatt_sr.cc:gatts_process_find_info: the same zero check is inserted after payload_size is computed and before buf_len is derived.
- system/stack/gatt/gatt_sr.cc:gatts_process_read_by_type_req: the same zero check is inserted before msg_len is computed and p_msg is allocated.
- system/stack/gatt/gatt_sr.cc:gatts_process_read_req: the same zero check is inserted before buf_len is computed.
- All four checks are identical trivial validity checks (Flag: EXEMPT). The fix is a single commit that adds 21 lines and touches no other files.
Completeness
- The fix covers the four server-side request handlers named in the diff. Each now returns silently when the payload size is 0.
- The fix does not send an error response or log anything. It only returns.
- gatt_build_primary_service_rsp (shown in context) also calls gatt_tcb_get_payload_size_tx without a zero check. It writes the opcode and length bytes before its payload_size comparison. It writes into the buffer allocated by gatts_process_primary_service_req, which is now guarded. The material does not show whether the two calls can return different values.
- The material does not show other uses of gatt_tcb_get_payload_size_tx elsewhere in the GATT stack, so they cannot be judged.
Behavior changes
- When the channel's payload size resolves to 0 (channel closed), the requests handled by these four functions are dropped without a response instead of being processed.
- No new error code, log or timeout is introduced.
Per major
- Android 14: same fix: commit c7468e64bb5e in android-security-14.0.0_r15 adds the four zero checks after the gatt_tcb_get_payload_size_tx calls. 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 adds the same four checks. On this branch the helper is named gatt_tcb_get_payload_size. 8/8 patched lines are present at android-security-15.0.0_r17.
- Android 16: not affected (not listed by the bulletin). 5/8 patched-region lines are present at android-security-16.0.0_r8.
- Android 17: not affected (not listed by the bulletin). 5/8 patched-region lines are present at android-security-17.0.0_r1.
Unknowns
- How the channel becomes closed while a request is still being processed. The material only says 'exceptional cases'.
- Whether other callers of gatt_tcb_get_payload_size_tx outside the four patched functions exist and are safe. The material does not show them.
- Why Android 16/17 show only a partial match of the patched region.