CVE-2025-48572 AI-generated analysis
platform/frameworks/base, services/core media (MediaSessionService / MediaButtonReceiverHolder)
MediaButtonReceiverHolder.send no longer attaches BroadcastOptions that grant background-activity-start and FGS temp-allowlist privileges to the media button receiver; it instead calls MediaSessionService.tempAllowlistTargetPkgIfPossible for the target package, with caller identity.
Root cause
In services/core/java/com/android/server/media/MediaButtonReceiverHolder.java, send() built BroadcastOptions with setTemporaryAppAllowlist(fgsAllowlistDurationMs, TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, REASON_MEDIA_BUTTON) and setBackgroundActivityStartsAllowed(true). It passed options.toBundle() both to mPendingIntent.send(...) and to context.sendBroadcastAsUser(...) in the legacy default path. These options gave the media button receiver (the package in the holder) background activity start and FGS allowlist capabilities without regard to the dispatching caller's identity. The commit message says this accidentally propagated BAL abilities to the receiver.
How the fix works
- MediaButtonReceiverHolder.java:send() - the signature now takes the MediaSessionService instance, callingPackageName, callingPid, callingUid and a separate reportedPackageName. The fgsAllowlistDurationMs parameter is removed.
- MediaButtonReceiverHolder.java:send() - the BroadcastOptions construction (setTemporaryAppAllowlist + setBackgroundActivityStartsAllowed(true)) is deleted. Instead, the target UID is resolved via context.getPackageManager().getPackageUidAsUser(mPackageName, mUserId), and mediaSessionService.tempAllowlistTargetPkgIfPossible(targetUid, mPackageName, callingPid, callingUid, callingPackageName, TAG) is called. NameNotFoundException is caught and only logged under DEBUG_KEY_EVENT.
- MediaButtonReceiverHolder.java:send() - mPendingIntent.send(...) now uses the 5-argument overload (context, resultCode, mediaButtonIntent, onFinishedListener, handler), with no requiredPermission or options bundle. The legacy default branch now calls context.sendBroadcastAsUser(mediaButtonIntent, userHandle) with no options bundle.
- MediaButtonReceiverHolder.java:send() - Intent.EXTRA_PACKAGE_NAME is now filled from reportedPackageName, which is the value previously passed as callingPackageName. The package name the receiver sees is unchanged.
- MediaSessionService.java (media key dispatch, mediaButtonReceiverHolder != null branch) - the local variable is renamed to reportedPackageName = asSystemService ? mContext.getPackageName() : packageName. The call to mediaButtonReceiverHolder.send now passes MediaSessionService.this, the raw packageName, pid, uid, reportedPackageName, resultCode, mKeyEventReceiver and mHandler. It no longer passes MediaSessionDeviceConfig.getMediaButtonReceiverFgsAllowlistDurationMs().
Completeness
- Both send paths in MediaButtonReceiverHolder.send that carried the options bundle are changed: the PendingIntent path and the legacy default sendBroadcastAsUser path. The options variable is removed, so no BAL grant from it remains in this method.
- FGS allowlisting now goes through MediaSessionService.tempAllowlistTargetPkgIfPossible. Its body is not in the diff, so the material does not show which conditions it applies.
- The session.sendMediaButton path in MediaSessionService is not touched by this fix. The material does not show whether it attaches comparable options. The non-default cases of the restored-intent switch are not changed by the diff and cannot reference the removed options variable.
- If getPackageUidAsUser throws NameNotFoundException, the send still goes ahead without any allowlisting.
Behavior changes
- Media button receivers no longer get a background-activity-start grant when MediaButtonReceiverHolder delivers the key event via PendingIntent or broadcast.
- FGS temporary allowlisting is no longer applied unconditionally via BroadcastOptions with the MediaSessionDeviceConfig duration. It is now delegated to MediaSessionService.tempAllowlistTargetPkgIfPossible with the caller's pid/uid/package, so the result depends on that method's checks.
- PendingIntent.send is called without the requiredPermission/options overload, and the legacy broadcast is sent without an options bundle.
- A debug log is emitted (under DEBUG_KEY_EVENT) when the receiver package cannot be resolved for the holder's user.
- MediaButtonReceiverHolder.send has a new, incompatible signature.
Per major
- Android 14: same fix: commit 7dcb4043f5d7 in android-security-14.0.0_r24, a manual cherry-pick of ag/33211293 (Change-Id I374a2f3a4acaac03e90ac9f9bbfccd47ffc1f4cf). The MediaSessionService hunk is at line ~2311.
- Android 15: same fix: commit 739ece18a63a in android-security-15.0.0_r12, identical diff content. The MediaSessionService hunk is at line ~2640.
- Android 16: same fix: commit e707f6600330 in android-security-16.0.0_r3, identical diff content. The MediaSessionService hunk is at line ~2677.
- Android 17: not affected (the bulletin does not list Android 17). At android-security-17.0.0_r1, 5/8 lines of the patched region are present. The material has no 17 commit.
Unknowns
- The implementation of MediaSessionService.tempAllowlistTargetPkgIfPossible and what conditions it checks before allowlisting.
- The Android 13 fix commit (the bulletin lists 13 as affected, but no diff is provided).
- Whether MediaSessionDeviceConfig.getMediaButtonReceiverFgsAllowlistDurationMs is still used elsewhere after this change.
- Whether the session.sendMediaButton path or the non-default restored-intent cases use any other BroadcastOptions.