CVE-2025-48586 AI-generated analysis
platform/packages/services/Telephony, Phone app settings (Fixed Dialing Numbers), com.android.phone.settings.fdn.EditFdnContactScreen
In Telephony's FDN contact editor, the onActivityResult handler now uses ComponentCaller.checkContentUriPermission to check that the caller holds a read grant for the returned contact URI. This replaces a user-ID comparison, and the handler throws SecurityException when the check is denied.
Root cause
EditFdnContactScreen.onActivityResult took the URI from the result Intent of a contact-pick activity and queried it with getContentResolver().query. The only gate was a comparison between UserHandle.getUserId(Process.myUid()) and ContentProvider.getUserIdFromUri(intent.getData(), currentUser). That checks the user ID encoded in the URI, with the current user as the default when the URI has none. It does not check whether the component that returned the result was allowed to read that URI. The fix commit's test steps involve a work-profile contact and a PoC app (bug 337784859).
How the fix works
- src/com/android/phone/settings/fdn/EditFdnContactScreen.java:onActivityResult (RESULT_OK branch): gets ComponentCaller currentCaller = getCurrentCaller() and Uri contactUri = intent != null ? intent.getData() : null. If contactUri is null, it logs and returns early.
- Same function: calls currentCaller.checkContentUriPermission(contactUri, Intent.FLAG_GRANT_READ_URI_PERMISSION). If the result is PackageManager.PERMISSION_DENIED, it writes an EventLog entry (tag 0x534e4554, bug 337784859, caller uid) and throws SecurityException naming the caller uid/package and the URI. The authorization question changes from 'does the URI claim to belong to my user' to 'does the caller have read access to this URI'.
- Same function: removes the old ContentProvider.getUserIdFromUri / Process.myUid() comparison and its imports (android.content.ContentProvider, android.os.Process). Adds imports for android.app.ComponentCaller, android.content.pm.PackageManager and android.util.EventLog. The getContentResolver().query call now uses the local contactUri.
Completeness
- The fix covers only the RESULT_OK path of EditFdnContactScreen.onActivityResult. This is the only place in the diff where a returned URI is queried.
- The check is tied to the read grant for the exact URI returned. The code no longer parses a user ID out of the URI, so a URI without a user prefix no longer passes by defaulting to the current user.
- The material does not show whether other activities in com.android.phone.settings.fdn (e.g. BaseFdnContactScreen or sibling screens) receive and query result URIs in the same way. Nothing in the provided diff or context touches them.
Behavior changes
- If the caller lacks read permission on the returned URI, onActivityResult now throws a SecurityException. Previously it logged a warning (Log.w) and returned for cross-user URIs, and went ahead with the query otherwise.
- A new EventLog SafetyNet entry (0x534e4554 / 337784859) is written on denial.
- A null Intent or null Intent.getData() is now handled explicitly by logging and returning.
- The check changed from user-ID matching to grant checking. A same-user URI returned without a read grant is now rejected, and the cross-user rejection based on the user ID in the URI is gone.
Per major
- Android 14: not affected per the bulletin (not listed); no fix commit shown. At android-security-14.0.0_r29, 7/8 lines of the patched region are present. The material does not explain this.
- Android 15: same fix: commit e4124fa76067 in android-security-15.0.0_r12 (cherry-pick of 522822360789, Change-Id I858041662a19a179e1fd49b3747d0fc013625015); 8/8 lines present at android-security-15.0.0_r17.
- Android 16: same fix: commit 851fc787e961 in android-security-16.0.0_r3, same hunks as the 15 commit; 8/8 lines present at android-security-16.0.0_r8.
- Android 17: not affected per the bulletin (not listed); 8/8 lines of the patched region present at android-security-17.0.0_r1.
Unknowns
- Whether other FDN screens or other Telephony activities use the same user-ID-based URI validation; the material only shows this one file.
- The state of the Android 14 code (7/8 lines of the patched region reported present).
- Whether the phone process's own contacts access is what let the old query succeed on URIs the caller could not read.
- Whether anything catches a SecurityException thrown from onActivityResult or whether it ends the Phone settings activity.
- Whether the earlier onActivityResult code (not shown) checked intent for null.