CVE-2024-0036 AI-generated analysis
platform/frameworks/base, services/core WindowManager/ActivityTaskManager (ActivityTaskManagerService.startNextMatchingActivity)
In ActivityTaskManagerService.startNextMatchingActivity, the fix makes the launch use ActivityOptions with setAvoidMoveToFront() (creating basic SafeActivityOptions when none were supplied), so the replacement activity cannot bring its task to the foreground. It also wraps the start in try/finally so the cleared Binder identity is always restored.
Root cause
startNextMatchingActivity clears the Binder calling identity and starts the next matching activity through ActivityStarter with setRealCallingUid(r.launchedFromUid), the UID of whatever launched the calling activity. It passes whatever ActivityOptions the caller supplied, possibly null. Nothing prevented the started activity from moving its task to the front. A later in-tree comment at android-security-14.0.0_r29 calls this a background activity launch through #startNextMatchingActivity: launchedFromUid may have BAL privileges (e.g. the Launcher), and the start uses its identity.
How the fix works
- services/core/java/com/android/server/wm/ActivityTaskManagerService.java:startNextMatchingActivity: after Binder.clearCallingIdentity(), a new SafeActivityOptions(ActivityOptions.makeBasic()) is created when options is null, so the launch always has options to constrain.
- Same function: options.getOptions(r).setAvoidMoveToFront() runs before the ActivityStarter is obtained. The start executed via obtainStarter(...).setActivityOptions(options).execute() therefore carries the avoid-move-to-front flag.
- Same function: the obtainStarter/execute block, the r.finishing = wasFinishing restore and the return now sit in a try block with Binder.restoreCallingIdentity(origId) in finally, so the identity is restored even if the start throws. The return becomes res == ActivityManager.START_SUCCESS, with the same meaning as before.
Completeness
- The fix only constrains move-to-front on the startNextMatchingActivity path. This commit leaves the other ActivityStarter fields in that call unchanged (setCaller(r.app.getThread()), setCallingPid(-1), setRealCallingUid(r.launchedFromUid)), so the start still runs with the original launcher's UID as real caller.
- At android-security-14.0.0_r29 the path has been reworked. realCallingUid/realCallingPid are now the actual Binder caller (origCallingUid/origCallingPid), with a comment citing b/230492947 and b/337726734. A further identity-forwarding restriction cites b/471797575.
- At r29 the setAvoidMoveToFront() call no longer sits at its original position right after the null-options check. This fits the per-major data (6/8 patched lines present). Whether it was moved further down is not shown.
Behavior changes
- Activities started via startNextMatchingActivity get avoidMoveToFront set on their options, even when the caller supplied its own ActivityOptions. Caller-supplied options are changed to set this flag.
- A caller that passed null options now has basic ActivityOptions attached to the launch.
- The Binder calling identity is now restored if the start sequence exits with an exception.
- Return value meaning is unchanged: true only on ActivityManager.START_SUCCESS.
Per major
- Android 14: Same fix: commit 3eaaa9687e90 in android-security-14.0.0_r5 (cherry-pick, Change-Id Ic88dd1e79b867b44cdcd6fc86650f5de6ebcc23d). By android-security-14.0.0_r29 the region has been rewritten further (realCallingUid now origCallingUid, identity-forwarding restriction, no setAvoidMoveToFront at its original position). 6/8 patched lines present.
- Android 15: Not affected per the bulletin (not listed). android-security-15.0.0_r17 has 6/8 of the patched lines. Its code is not shown.
- Android 16: Not affected per the bulletin (not listed). android-security-16.0.0_r8 has 7/8 of the patched lines. Its code is not shown.
- Android 17: Not affected per the bulletin (not listed). android-security-17.0.0_r1 has 6/8 of the patched lines. Its code is not shown.
Unknowns
- Whether setAvoidMoveToFront() was moved elsewhere or removed in the latest 14/15/16/17 security tags. The r29 context does not show it at its original position and ends at line 1444.
- The exact content of the follow-up changes (b/337726734, b/471797575) and whether they belong to this CVE.
- How the activity token is checked before r is used (not in the provided context).
- Details of BackgroundActivityLaunchTest#testBackgroundActivityBlockedInStartNextMatchingActivity (not in the diff).