CVE-2025-22412 AI-generated analysis
platform/packages/modules/Bluetooth, system/stack (AVCT, BNEP, HID device, RFCOMM, SDP client and server)
At nine Bluetooth stack call sites, the log::warn issued after a failed L2CA_DataWrite no longer reads the length from a BT_HDR buffer (p_buf->len, p->len, hd_cb.pending_data->len) that may already have been freed. The length is now captured before the call or taken from a pointer difference computed earlier.
Root cause
Several profiles send a BT_HDR with L2CA_DataWrite(cid, p_buf). When the call does not return L2CAP_DW_SUCCESS, they log the length by reading p_buf->len (or p->len, or hd_cb.pending_data->len) after the call. Per the commit message, these structures may in exceptional cases have been freed by the preceding call, so the log statement can read freed memory. Affected sites: avct_lcb_act.cc:avct_lcb_msg_ind (AVCT_REJ response), bnep_main.cc:bnep_congestion_ind (draining xmit_q), bnep_utils.cc:bnepu_check_send_packet, hidd_conn.cc:hidd_check_config_done (pending interrupt data), rfc_ts_frames.cc:rfc_send_buf_uih, rfc_utils.cc:rfc_check_send_cmd (draining cmd_q), sdp_discovery.cc:process_service_attr_rsp, and sdp_server.cc:process_service_search and process_service_attr_req.
How the fix works
- avct_lcb_act.cc:avct_lcb_msg_ind: adds `uint16_t len = p_buf->len;` before L2CA_DataWrite and logs `len` instead of p_buf->len.
- bnep_main.cc:bnep_congestion_ind: same pattern inside the xmit_q drain loop. `len` is captured after fixed_queue_try_dequeue and before L2CA_DataWrite.
- bnep_utils.cc:bnepu_check_send_packet: captures `len` in the non-congested branch before L2CA_DataWrite. The congested branch (enqueue or osi_free) is unchanged.
- hidd_conn.cc:hidd_check_config_done: captures `uint16_t len = hd_cb.pending_data->len;` before L2CA_DataWrite(p_hcon->intr_cid, hd_cb.pending_data) and logs `len`. hd_cb.pending_data is still set to NULL afterwards. The new lines are indented inconsistently, but the logic is correct.
- rfc_ts_frames.cc:rfc_send_buf_uih: captures `len` in the non-RFCOMM_MX_DLCI branch before L2CA_DataWrite(p_mcb->lcid, p_buf).
- rfc_utils.cc:rfc_check_send_cmd: captures `uint16_t len = p->len;` for each dequeued command buffer before L2CA_DataWrite.
- sdp_discovery.cc:process_service_attr_rsp: logs `p - p_start`, the value just assigned to p_msg->len, instead of reading p_msg.
- sdp_server.cc:process_service_search and process_service_attr_req: log `p_rsp - p_rsp_start`, the value just assigned to p_buf->len, instead of reading p_buf.
- L2CA_DataWrite itself is not changed. The fix only removes reads of the buffer after the call at these call sites.
Completeness
- Covers nine L2CA_DataWrite call sites in eight files. At each site, the only use of the buffer after the call was the length argument of log::warn, and that read is removed.
- The commit title 'Fix more memory-unsafe logging' suggests an earlier change fixed other sites. That commit is not in the material, so coverage across the whole stack cannot be judged here.
- The material does not show other L2CA_DataWrite callers that may read the buffer after the call, and this commit does not modify any.
- The logged values have the same meaning as before (the BT_HDR length at call time).
Behavior changes
- No functional change. The same length value is logged, now read from a local variable or recomputed from pointers instead of from the buffer after the call.
Per major
- Android 14: Not affected per the bulletin (not listed). At android-security-14.0.0_r29, 4/8 lines of the patched region are present.
- Android 15: Same fix: commit 806774b1cf64 in android-security-15.0.0_r5 (cherry-picked from internal 43cfd234de9b, Change-Id I6289907e86786eb2e10a163f7fb5d2557eab00bc). At android-security-15.0.0_r17 the code context shows all nine sites in fixed form, with a 7/8 line match of the patched region.
- Android 16: Not affected per the bulletin (not listed). At android-security-16.0.0_r8, 4/8 lines of the patched region are present.
- Android 17: Not affected per the bulletin (not listed). At android-security-17.0.0_r1, 4/8 lines of the patched region are present.
Unknowns
- Which of the nine sites the researcher POC targeted, and the exact condition under which the buffer is freed before the log statement.
- What the earlier companion commit implied by 'Fix more memory-unsafe logging' contains, and whether other L2CA_DataWrite callers still read the buffer after the call.
- The state of these sites on Android 14, 16 and 17. The bulletin does not list them, and only 4/8 lines of the patched region match.
- Why only 7/8 lines of the patched region match at android-security-15.0.0_r17.