CVE-2024-49737 AI-generated analysis
platform/frameworks/base, WindowManager (services/core/java/com/android/server/wm: WindowOrganizerController, ActivityStartController)
In WindowOrganizerController, the OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT handler now builds a SafeActivityOptions from the operation's options Bundle using the actual caller's pid/uid (caller.mPid, caller.mUid), and ActivityStartController.startActivityInTaskFragment now takes that SafeActivityOptions instead of a raw Bundle.
Root cause
Per the commit message, WindowOrganizerController clears the calling uid before applying the WindowContainerTransaction, but SafeActivityOptions queries the Binder uid when it is constructed. Before the fix, the OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT case passed the raw options Bundle (operation.getBundle()) to ActivityStartController.startActivityInTaskFragment, so the options were not explicitly tied to the actual caller's uid/pid.
How the fix works
- services/core/java/com/android/server/wm/WindowOrganizerController.java, OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT case: after reading operation.getBundle(), the fix calls SafeActivityOptions.fromBundle(activityOptions, caller.mPid, caller.mUid), which binds the options to the caller's pid/uid (the same caller.mUid/caller.mPid already passed as callingUid/callingPid). It then passes safeOptions to startActivityInTaskFragment instead of the Bundle.
- services/core/java/com/android/server/wm/ActivityStartController.java, startActivityInTaskFragment(): parameter type changed from @Nullable Bundle to @Nullable SafeActivityOptions (unused android.os.Bundle import removed, javadoc updated).
- Because the parameter type changed, any caller of startActivityInTaskFragment must now pass a SafeActivityOptions.
Completeness
- Covers the TaskFragment start-activity operation in WindowOrganizerController. In the diff, that is the only call site of startActivityInTaskFragment that changed.
- The bodies of SafeActivityOptions and startActivityInTaskFragment are not in the material, so how the options are later validated against the supplied pid/uid is not visible.
- The other cases shown in the same switch (create, delete, reparent) do not pass an options Bundle and are not touched. Whether other WCT paths construct SafeActivityOptions under a cleared identity is not shown.
Behavior changes
- Options supplied with a TaskFragment start-activity operation are now bound to the caller's uid/pid via SafeActivityOptions.fromBundle. The resulting effect on permission-gated options is not shown.
- Internal API change: ActivityStartController.startActivityInTaskFragment takes SafeActivityOptions instead of Bundle.
Per major
- Android 13: Listed as affected by the bulletin; no Android 13 commit is in the material, so how it was applied there is unknown.
- Android 14: Same fix: commit 5eb2aa58018c in android-security-14.0.0_r16 (cherry-pick of 20c568e77eae); 8/8 lines of the patched region present at android-security-14.0.0_r29.
- Android 15: Adapted fix: commit 4b2a235c895c in android-security-15.0.0_r4; same change, but the call sits inside waitAsyncStart(() -> ...) in WindowOrganizerController; 8/8 lines present at android-security-15.0.0_r17.
- Android 16: Not affected (not listed by the bulletin); patched region (8/8 lines) present at android-security-16.0.0_r8.
- Android 17: Not affected (not listed by the bulletin); patched region (8/8 lines) present at android-security-17.0.0_r1.
Unknowns
- The bodies of startActivityInTaskFragment and SafeActivityOptions: where the Binder identity was previously captured and which options are permission-gated.
- Which specific options were affected, and the exact behavior after the fix.
- Whether an Android 13 patch exists and its form.