CVE-2025-48529 AI-generated analysis
platform/frameworks/opt/telephony, voicemail notification settings (VoicemailNotificationSettingsUtil, NotificationChannelController)
Removes the shared-preference storage, readback and channel migration of the voicemail ringtone URI in frameworks/opt/telephony, so TelephonyManager#setVoicemailRingtoneUri becomes a no-op and getVoicemailRingtoneUri only returns the voicemail NotificationChannel sound.
Root cause
VoicemailNotificationSettingsUtil.setRingtoneUri wrote any URI passed through TelephonyManager#setVoicemailRingtoneUri into the phone process default SharedPreferences. Per index search, that call goes through PhoneInterfaceManager.setVoicemailRingtoneUri, which is reachable by the default dialer or by callers that pass the modify-permission or carrier-privilege check. Two legacy paths then consumed the stored value. First, getRingtoneUri fell back to getRingTonePreference when the voicemail channel did not exist. Second, NotificationChannelController.migrateVoicemailNotificationSettings called getRingTonePreference and set the URI as the sound of the newly created CHANNEL_ID_VOICE_MAIL channel. The commit message states that a URI set via the setter could be migrated onto the notification channel, causing a cross-profile exploit. The pre-P shared preference mechanism was obsolete (the setting has lived on the NotificationChannel since Android P) but was still writable and readable.
How the fix works
- src/java/com/android/internal/telephony/util/VoicemailNotificationSettingsUtil.java:setRingtoneUri: the body is replaced with a no-op comment; the URI is no longer written to SharedPreferences.
- VoicemailNotificationSettingsUtil.java:getRingtoneUri: the fallback to getRingTonePreference(context) is removed. It returns channel.getSound() if the CHANNEL_ID_VOICE_MAIL channel exists, otherwise null. A comment is added saying never to look at the shared preferences.
- VoicemailNotificationSettingsUtil.java: getRingTonePreference(Context) is deleted entirely (it read the pref, invoked migrateVoicemailRingtoneSettingsIfNeeded and parsed the stored string into a Uri). The unused imports android.provider.Settings and android.text.TextUtils are removed.
- src/java/com/android/internal/telephony/util/NotificationChannelController.java:migrateVoicemailNotificationSettings: removes the Uri sound = getRingTonePreference(context) lookup and the voiceMailChannel.setSound(...) call, so the voicemail channel is created without a sound taken from shared preferences. The android.net.Uri import and the javadoc reference to getRingTonePreference are removed.
- Single commit with an identical diff (same blob hashes) on 14, 15 and 16.
Completeness
- Covers the three uses of the ringtone shared preference shown in the diff: the setter, the getter fallback, and the channel migration.
- The vibration setting (setVibrationEnabled/getVibrationPreference) still uses SharedPreferences and is still applied to the channel in migrateVoicemailNotificationSettings. It is a boolean, not a URI, and is left unchanged.
- The diff does not show migrateVoicemailRingtoneSettingsIfNeeded or getVoicemailRingtoneSharedPrefsKey being removed. The VOICEMAIL_NOTIFICATION_RINGTONE_SHARED_PREFS_KEY_PREFIX constant remains in the code context at r29.
- Ringtone values stored before the fix are not deleted from the phone process shared preferences. The readers shown in the diff are removed.
- PhoneInterfaceManager.setVoicemailRingtoneUri (packages/services/Telephony) is not modified (per index search). It still performs permission checks and calls the now no-op setRingtoneUri.
Behavior changes
- TelephonyManager#setVoicemailRingtoneUri silently does nothing (no error is returned to the caller).
- TelephonyManager#getVoicemailRingtoneUri returns null instead of the shared-preference or default notification URI when the voicemail NotificationChannel does not exist.
- When migrateVoicemailNotificationSettings creates the voicemail notification channel, it no longer calls setSound with a legacy preference value or DEFAULT_NOTIFICATION_URI.
Per major
- Android 14: same fix: commit 122251ced157 in android-security-14.0.0_r22; patched region present at android-security-14.0.0_r29 (7/8 lines).
- Android 15: same fix: commit e5cdca27526f in android-security-15.0.0_r10, identical diff; patched region present at android-security-15.0.0_r17 (7/8 lines).
- Android 16: same fix: commit f33f9ef6467b in android-security-16.0.0_r1, identical diff; patched region present at android-security-16.0.0_r8 (7/8 lines).
- Android 17: not affected per the bulletin; at android-security-17.0.0_r1, 7/8 lines of the patched region are present.
Unknowns
- The bulletin lists Android 13 as affected, but the material has no Android 13 fix commit.
- The exact cross-profile disclosure mechanism is not shown beyond the commit message statement.
- Whether migrateVoicemailRingtoneSettingsIfNeeded and getVoicemailRingtoneSharedPrefsKey still have callers after the fix, or remain as dead code, is not shown.
- The sound the voicemail channel gets when created without an explicit setSound call is not shown in the material.