CVE-2026-28612 AI-generated analysis
platform/frameworks/base, services/core WindowManager activity start (ActivityStarter, ActivityStartController)
Reorders activity start so that the intent-redirect checks (the EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN check and the IntentCreatorToken-based creator uid/package extraction) run before supervisor.resolveIntent/resolveActivity in both ActivityStarter and ActivityStartController, so that intent resolution can no longer change the intent's component and invalidate the creator token before it is checked.
Root cause
In ActivityStarter (the request resolution block around line 606) and in the ActivityStartController per-intent loop (around line 437), the code first called supervisor.resolveIntent/resolveActivity. Only afterwards did it check EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN (ActivityStarter only) and call IntentCreatorToken.isValid(intent) to extract the creator uid/package. resolveActivity can modify the intent: the existing comment in ActivityStartController says "the intent may be modified in resolveActivity below", and the commit message says resolveActivity changes the intent's component, which invalidates the creatorToken. In the patched region of the ActivityStartController loop there was no MISSING_CREATOR_OR_INVALID_TOKEN check before the fix.
How the fix works
- ActivityStarter.java (request resolution block before 'Carefully collect grants'): the supervisor.resolveIntent(...) call, the resolveIntentForLockedOrStoppedProfiles fallback and supervisor.resolveActivity(...) are moved below the existing 'Check if the Intent was redirected' block. The EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN check (logAndThrowExceptionForIntentRedirect) and the IntentCreatorToken.isValid(intent) extraction of intentCreatorUid/intentCreatorPackage now operate on the unresolved intent copy.
- ActivityStartController.java (per-intent loop over intents[]): the mSupervisor.resolveActivity(...) and mService.mAmInternal.getActivityInfoForUser(...) calls are moved after the creator-token handling. A new check is added: if EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN is set, the loop calls ActivityStarter.logAndAbortForIntentRedirect(mService.mContext, INTENT_REDIRECT_EXCEPTION_MISSING_OR_INVALID_TOKEN, intent, creatorUid, creatorPackage, filterCallingUid, callingPackage) and returns START_CANCELED when that call returns true. The ActivityManagerService.IntentCreatorToken.isValid(intent) extraction of creatorUid/creatorPackage follows, and resolution comes last.
- ActivityStarter.java: logAndAbortForIntentRedirect is changed from 'private static' to package-private 'static' so that ActivityStartController can call it.
Completeness
- Both resolution sites shown in the diff (ActivityStarter request resolution and the ActivityStartController multi-intent loop) are reordered in the same way.
- The ActivityStartController loop gains a MISSING_CREATOR_OR_INVALID_TOKEN abort that the patched region did not have before. The material does not show whether that condition was enforced elsewhere on that path.
- The fix only reorders checks. It does not change how resolveActivity mutates the intent or how IntentCreatorToken.isValid validates the token. If any other start path resolves the intent before consulting the creator token, it is not visible in the material and this diff does not address it.
- After the fix, the two sites behave differently on a missing or invalid token. ActivityStarter calls logAndThrowExceptionForIntentRedirect with resolvedCallingUid. ActivityStartController calls logAndAbortForIntentRedirect with filterCallingUid and returns START_CANCELED; this check is new in this fix.
Behavior changes
- The creator uid/package used for intent redirect handling are now derived from the intent before resolution.
- New early return of START_CANCELED (with a Slog.d message) in the ActivityStartController multi-intent loop when the intent carries EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN and logAndAbortForIntentRedirect returns true.
- In ActivityStarter, the missing/invalid-token check (logAndThrowExceptionForIntentRedirect) now runs before intent resolution instead of after it.
- The visibility of logAndAbortForIntentRedirect is widened to package-private.
Per major
- Android 14: Not affected per the bulletin. At android-security-14.0.0_r29, 4/8 lines of the patched region are present. No fix applied.
- Android 15: Not affected per the bulletin. At android-security-15.0.0_r17, 6/8 lines of the patched region are present. No fix applied.
- Android 16: Same fix: commit f7398bb64526 in android-security-16.0.0_r8 (cherry-pick, Change-Id Iae6a7ef5cb569e1436c9a705b686488bf348b5ff). 8/8 lines present.
- Android 17: Same fix: commit a2f24fcecabd in android-security-17.0.0_r1, identical hunks at shifted line offsets. 8/8 lines present.
Unknowns
- How IntentCreatorToken.isValid validates the token (which intent fields are bound) and exactly how resolveActivity alters the component. Only the commit message states that the component change invalidates the token.
- What concretely happened downstream before the fix when the token was invalidated (for example, whether creatorUid stayed at DEFAULT_INTENT_CREATOR_UID and how later enforcement was affected).
- Whether logAndAbortForIntentRedirect always aborts or depends on a flag or enforcement mode (it returns a boolean), and whether logAndThrowExceptionForIntentRedirect always throws.
- Whether other activity start entry points outside these two sites perform creator-token checks after resolution.
- Whether Android 14/15 contain the creator-token logic; the material gives only partial line counts.