CVE-2024-40654 AI-generated analysis
platform/packages/apps/Settings, search (SearchResultTrampoline / SearchFeatureProviderImpl)
SearchResultTrampoline now identifies its launcher with getLaunchedFromPackage() instead of getCallingActivity(), and SearchFeatureProvider.verifyLaunchSearchResultPageCaller now takes the launching package name instead of the result-receiving ComponentName.
Root cause
SearchResultTrampoline.onCreate took the identity of whoever launched the trampoline from getCallingActivity(). It passed that value to SearchFeatureProviderImpl.verifyLaunchSearchResultPageCaller, which allowed the launch if the package was Settings, the SettingsIntelligence package, or signature-allowlisted. The same ComponentName also drove the isSettingsIntelligence() branch, which selects how the result page is launched (including DeepLinkHomepageActivityInternal). The commit message says getCallingActivity() reports who will get the Activity result, not who launched the activity or built the PendingIntent used to launch it. The privilege check was therefore keyed on a value that does not identify the launching package.
How the fix works
- src/com/android/settings/search/SearchResultTrampoline.java:onCreate: replaces getCallingActivity() with getLaunchedFromPackage(), which returns a String, and passes it to verifyLaunchSearchResultPageCaller. The same value is then used for the isSettingsIntelligence() branch.
- src/com/android/settings/search/SearchResultTrampoline.java:isSettingsIntelligence: the parameter changes from ComponentName to String. The method is now a plain TextUtils.equals against getSettingsIntelligencePkgName(this), and the explicit null check is dropped. TextUtils.equals handles null (general platform knowledge).
- src/com/android/settings/search/SearchFeatureProvider.java: the interface method changes to verifyLaunchSearchResultPageCaller(@NonNull Context, @NonNull String callerPackage).
- src/com/android/settings/search/SearchFeatureProviderImpl.java:verifyLaunchSearchResultPageCaller: the null check becomes TextUtils.isEmpty(callerPackage), which throws IllegalArgumentException. The isSettingsPackage comparison and isSignatureAllowlisted now use callerPackage directly. The decision logic is otherwise unchanged. The unused TAG and the ComponentName import are removed.
- tests/robotests/.../SearchFeatureProviderImplTest.java: the three existing tests now pass package name strings instead of ComponentName.
Completeness
- Covers both uses of the caller identity in SearchResultTrampoline: the privilege check and the isSettingsIntelligence() launch-mode branch. Both now use the launching package.
- The allowlist logic itself (isSignatureAllowlisted, and the Settings and SettingsIntelligence package comparisons) is unchanged. Only the identity passed into it changes.
- The IllegalArgumentException message still says the intents 'must be called with startActivityForResult', which no longer matches the new identity source. This is cosmetic.
- The material shows no other callers of verifyLaunchSearchResultPageCaller. Custom SearchFeatureProvider implementations are outside the material.
Behavior changes
- The caller identity is now the package reported by getLaunchedFromPackage() (the launcher, or whoever built the PendingIntent), not the package of the result-receiving activity.
- An empty or null caller package now throws IllegalArgumentException (TextUtils.isEmpty check).
- SearchFeatureProvider interface signature change: every implementation of verifyLaunchSearchResultPageCaller must switch to the String parameter.
Per major
- Android 14: same fix: f1d0079c9173 (Change-Id If97018c2741caef622f0596bbfeaa42ef1788b78, cherry-picked from 901880a1d2e6) in android-security-14.0.0_r8. 7/8 lines of the patched region are still present at android-security-14.0.0_r29.
- Android 15: fix present in base android-15.0.0_r1 through merge commit a339d8ea9a16 ([RESTRICT AUTOMERGE] merge from sc-v2-dev); its combined diff in SearchResultTrampoline contains isSettingsIntelligence(callerPackage). Only 2/8 lines of the patched region match at android-security-15.0.0_r17, and the material does not explain why.
- Android 16: not affected (not listed by the bulletin); 7/8 lines of the patched region present at android-security-16.0.0_r8.
- Android 17: not affected (not listed by the bulletin); 7/8 lines of the patched region present at android-security-17.0.0_r1.
Unknowns
- Whether SearchResultTrampoline is exported and which intent filters or actions reach it (the manifest is not in the material).
- The concrete scenario in which getCallingActivity() reported an allowed package for a non-allowed launcher (no details of bug 316891059 are provided).
- What getLaunchedFromPackage() returns for each launch mode (plain startActivity, startActivityForResult, PendingIntent), and so which exception each launch path now gets.
- The contents of isSignatureAllowlisted and of the allowlist itself.
- Why only 2/8 lines of the patched region match on Android 15.