CVE-2025-26438 AI-generated analysis
platform/packages/modules/Bluetooth, system/stack/smp (Security Manager Protocol, LE Secure Connections OOB pairing)
Adds a check in smp_process_secure_connection_oob_data that aborts LE Secure Connections OOB pairing with SMP_OOB_FAIL when the peer's OOB flag is SMP_OOB_PRESENT but no local OOB data is stored, instead of continuing with a zeroed local randomizer.
Root cause
In system/stack/smp/smp_act.cc, smp_process_secure_connection_oob_data() is invoked from smp_start_secure_connection_phase1() when the selected association model is SMP_MODEL_SEC_CONN_OOB, a model for which p_cb->sec_level is set to SMP_SEC_AUTHENTICATED. Per the commit message, when no local OOB data is available the stack sets the local OOB randomizer to zero (p_cb->local_random = {0}) and continues. Nothing verified that a peer which flagged OOB data as present (p_cb->peer_oob_flag == SMP_OOB_PRESENT) could actually have obtained local OOB data. Per the commit message, a malicious peer could therefore claim to have OOB data and proceed with pairing against the zero randomizer, bypassing SMP authentication.
How the fix works
- system/stack/smp/smp_act.cc:smp_process_secure_connection_oob_data: right after the existing block that sets p_cb->local_random = {0} (the zero fallback the commit message describes for missing local OOB data), a new check tests p_cb->peer_oob_flag == SMP_OOB_PRESENT && !p_sc_oob_data->loc_oob_data.present.
- If the condition holds it logs a warning, builds a tSMP_INT_DATA with status = SMP_OOB_FAIL, posts SMP_AUTH_CMPL_EVT to the SMP state machine via smp_sm_event(), and returns, so the peer-OOB processing and the rest of the OOB phase-1 flow are not reached for that connection.
- The check is placed before the peer_oob_data.present handling, so it applies regardless of whether peer OOB data was locally stored.
Completeness
- Covers only the LE Secure Connections OOB path (smp_process_secure_connection_oob_data, reached via smp_start_secure_connection_phase1 for SMP_MODEL_SEC_CONN_OOB). Legacy (non-SC) pairing OOB handling is not part of the diff and the material does not show whether an analogous check exists there.
- The fix does not change the fallback that sets p_cb->local_random = {0}; it only prevents proceeding when the peer claims OOB while local OOB data is absent.
- The reverse mismatch (local OOB data present while the peer does not claim OOB) is not addressed by this change; the material does not show whether it is relevant.
- The check dereferences p_sc_oob_data; the diff does not add a null check and the surrounding retrieval of p_sc_oob_data is not shown.
Behavior changes
- SC OOB pairing now fails with SMP_AUTH_CMPL_EVT / status SMP_OOB_FAIL (connection dropped per the log message) when the peer flags OOB present but no local OOB data has been stored; previously pairing continued with a zero local randomizer.
- New warning log line: "local OOB data is not present but peer claims to have received it; dropping connection" (SMP_TRACE_WARNING on 14, log::warn on 15).
Per major
- Android 14: same fix: commit 022ac90c296b in android-security-14.0.0_r20, uses SMP_TRACE_WARNING with __func__; at android-security-14.0.0_r29 4/4 lines of the patched region present.
- Android 15: adapted fix: commit e6130675c047 in android-security-15.0.0_r8, identical logic but uses log::warn without __func__ and different line wrapping; at android-security-15.0.0_r17 4/4 lines present.
- Android 16: not affected per the bulletin (not listed); at android-security-16.0.0_r8 3/4 lines of the patched region present. The exact code is not shown in the material.
- Android 17: not affected per the bulletin (not listed); at android-security-17.0.0_r1 3/4 lines of the patched region present. The exact code is not shown in the material.
Unknowns
- How p_cb->peer_oob_flag is populated from the peer's pairing PDU and whether it is validated elsewhere (not shown).
- The exact condition guarding the existing local_random = {0} block (only its tail is shown in the diff).
- Whether the legacy (non-SC) pairing OOB path has an analogous issue or check.
- The exact state of the patched region on Android 16 and 17 (only a 3/4 line match is reported) and why the bulletin does not list them.
- Whether p_sc_oob_data can be null at this point.