CVE-2025-26453 AI-generated analysis
platform/packages/modules/Bluetooth, OPP (Object Push Profile) send path, android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
Changes BluetoothOppSendFileInfo.isContentUriForOtherUser to derive the user id from the decoded Uri authority (text before the last '@') instead of Uri.getUserInfo(), so Bluetooth OPP's cross-user content URI check agrees with how ContentProvider resolves the target user.
Root cause
isContentUriForOtherUser() in BluetoothOppSendFileInfo.java got the user id from uri.getUserInfo(). The new Javadoc in the diff explains that ContentProvider APIs instead pass the decoded Uri.getAuthority() to ContentProvider#getUserIdFromAuthority. ContentProvider therefore treats an encoded '@' ('%40') in the authority as the separator between userInfo and host, but Uri.getUserInfo() does not treat it as a separator. A content URI that put another user's id in front of an encoded '@' could pass the OPP check while being resolved by ContentProvider as another user's URI. This is consistent with the bulletin type ID (information disclosure).
How the fix works
- BluetoothOppSendFileInfo.java:isContentUriForOtherUser: replaces `String uriUserId = uri.getUserInfo();` with these steps: get `uri.getAuthority()` (decoded form); return false if it is null; find `authority.lastIndexOf('@')`; return false if there is none; take `authority.substring(0, atIndex)` as uriUserId. The existing tail is kept: return true if and only if uriUserId is non-empty and differs from String.valueOf(myUserId()). Per the Javadoc, this mirrors the ContentProvider parsing.
- BluetoothOppSendFileInfoTest.java: switches the runner to TestParameterInjector and parameterizes generateFileInfo_withContentUriForOtherUser_returnsSendFileInfoError and generateFileInfo_withContentUriForSameUser_returnsInfoWithCorrectLength on `boolean encodedAt`, building authorities with either '@media' or '%40media'. In the Android 14 commit, the other-user test is also marked @Ignore (b/377774165, prebuilt BT APEX).
- android/app/tests/unit/Android.bp (Android 14 commit only): adds "TestParameterInjector" to static_libs of BluetoothInstrumentationTestsDefaults.
Completeness
- Only the helper isContentUriForOtherUser is changed. Per the Javadoc, getAuthority() returns the decoded authority, so the fix covers both a literal '@' and a percent-encoded '%40'.
- The check compares strings rather than parsing an int, so any non-empty userInfo that is not exactly the current user's id string is treated as another user.
- An authority with an '@' but an empty prefix still returns false (TextUtils.isEmpty), as before. The material does not show how ContentProvider treats that case.
- The material does not show where isContentUriForOtherUser is called inside generateFileInfo, so it cannot confirm that every content-URI path in OPP goes through this check.
Behavior changes
- Content URIs whose decoded authority has a userInfo prefix before '@' that differs from the current user id are now treated as other-user URIs, including when the '@' was percent-encoded. Per the test name, generateFileInfo returns SEND_FILE_INFO_ERROR for them.
- URIs whose userInfo equals the current user id are still accepted (covered by the same-user test in both encoded and unencoded forms).
- Test-only: BluetoothOppSendFileInfoTest now uses TestParameterInjector. The Android 14 commit also adds the TestParameterInjector static_lib and an @Ignore on one test.
Per major
- Android 14: Resolved via bug_id in android-security-14.0.0_r21, commit 0d3683c8b1c1 (RESTRICT AUTOMERGE, double cherry-pick). Same source change to isContentUriForOtherUser. Unlike 15/16, it does not add the `import android.content.ContentProvider;` line, and it adds TestParameterInjector to tests/unit/Android.bp plus an @Ignore on the other-user test. At android-security-14.0.0_r29, 7/8 lines of the patched region are present.
- Android 15: Resolved via bug_id in android-security-15.0.0_r9, commit 495d32429fd8. Same fix, plus `import android.content.ContentProvider;` (referenced by the Javadoc {@link} in the shown hunks). The commit has no Android.bp change. At android-security-15.0.0_r17, 7/8 lines are present.
- Android 16: Resolved in base android-16.0.0_r2, commit bb8a03783901. Same fix as Android 15. At android-security-16.0.0_r8, 7/8 lines are present.
- Android 17: Not affected (not listed by the bulletin). At android-security-17.0.0_r1, 7/8 lines of the patched region are present.
Unknowns
- The call sites of isContentUriForOtherUser within generateFileInfo, and the OPP entry points that reach it, are not in the provided code context.
- The material does not show why the per-major line match is 7/8 rather than 8/8 in every tag.
- The exact semantics of ContentProvider#getUserIdFromAuthority (for example, empty userInfo or multiple '@') are described only by the fix's Javadoc, not by framework code in the material.