CVE-2024-43088 AI-generated analysis
platform/packages/apps/Settings, applications (AppInfoBase / app info fragments)
Settings AppInfoBase.retrieveAppEntry now calls finish() when the launching intent's EXTRA_USER_HANDLE names a user other than the current one and the initial calling package does not hold INTERACT_ACROSS_USERS_FULL.
Root cause
In src/com/android/settings/applications/AppInfoBase.java, retrieveAppEntry() read Intent.EXTRA_USER_HANDLE from the launching intent and used it directly as mUserId, without checking whether the caller was allowed to interact across users. The fragment could therefore be pointed at a package in a different user.
How the fix works
- AppInfoBase.java:retrieveAppEntry(): after taking mUserId from EXTRA_USER_HANDLE, if mUserId != UserHandle.myUserId() and hasInteractAcrossUsersPermission() is false, it logs 'Intent not valid.', calls finish() and returns an empty string, so mPackageInfo/mAppEntry are never filled in for the foreign user.
- AppInfoBase.java:hasInteractAcrossUsersPermission() (new, @VisibleForTesting protected): returns false unless getActivity() is a SettingsActivity. It then gets ((SettingsActivity) activity).getInitialCallingPackage() and returns false if that is empty, or if mPm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingPackageName) != PERMISSION_GRANTED. Otherwise it returns true.
- tests/robotests/.../AppInfoWithHeaderTest.java: TestFragment overrides hasInteractAcrossUsersPermission() to return true so existing cross-user tests still pass. The new TestFragmentWithoutPermission returns false, and the new test noCrossUserPermission_retrieveAppEntry_fail asserts that mAppEntry stays null.
Completeness
- The fix covers only the EXTRA_USER_HANDLE path in AppInfoBase.retrieveAppEntry(). Intents without that extra are unchanged and default to UserHandle.myUserId().
- The check fails closed: a host activity that is not a SettingsActivity, or an empty initial calling package, both lead to finish().
- The permission check is by package name through PackageManager.checkPermission, keyed on SettingsActivity.getInitialCallingPackage(). It does not check the calling uid. Its correctness therefore depends on how SettingsActivity records the initial calling package, which the material does not show.
- The same-user case (mUserId == myUserId) is still allowed without any check, as before the fix.
- The material does not show whether other Settings fragments outside AppInfoBase consume EXTRA_USER_HANDLE in a similar way.
Behavior changes
- App-info fragments derived from AppInfoBase now call finish() (and log a 'Intent not valid.' warning) when launched with EXTRA_USER_HANDLE for another user by a caller that lacks INTERACT_ACROSS_USERS_FULL.
- Fragments hosted in an activity that is not a SettingsActivity are now also finished for cross-user intents, because hasInteractAcrossUsersPermission() returns false in that case.
- New warning logs appear when the calling package cannot be determined or lacks the permission.
Per major
- Android 14: same fix: commit 975c28535419 in android-security-14.0.0_r14; patched region 8/8 lines present at android-security-14.0.0_r29.
- Android 15: not affected (not listed by the bulletin); patched region 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 material does not show how SettingsActivity.getInitialCallingPackage() is implemented or how reliably it reflects the actual launching caller.
- The material does not show which concrete AppInfoBase subclasses and exported Settings entry points could be reached with EXTRA_USER_HANDLE, or by which callers.
- The bulletin lists 12, 12L and 13 as affected, but the material gives no fix commit or tag status for those branches.