CVE-2024-40657 AI-generated analysis
platform/packages/apps/Settings, accounts (AccountTypePreferenceLoader)
Settings' AccountTypePreferenceLoader now neutralizes clicks on any preference inflated from an external account authenticator's accountPreferences XML whose android:fragment is not already present in the host preference group, so that external apps cannot have Settings open its internal fragments.
Root cause
AccountTypePreferenceLoader takes the preference XML that an account authenticator references through desc.accountPreferencesId (a resource owned by the external authenticator package) and inflates it into a Settings PreferenceFragmentCompat with mFragment.getPreferenceManager().inflateFromResource(themedCtx, desc.accountPreferencesId, parent). Before this fix, nothing checked the android:fragment attribute of the inflated preferences. A preference supplied by the external app could therefore name a fragment class that would open inside Settings when tapped, giving external applications access to internal Settings fragments (per the commit comment).
How the fix works
- src/com/android/settings/accounts/AccountTypePreferenceLoader.java, in the method that loads desc.accountPreferencesId: before inflation, it calls the new generateFragmentAllowlist(parent). This collects every non-empty Preference.getFragment() value already present in the host group, recursing through nested PreferenceGroups.
- Same method: directly after inflateFromResource(...), it calls the new filterBlockedFragments(prefs, fragmentAllowList). This recursively walks the inflated group. For every Preference whose getFragment() is non-null and not in the allowlist, it installs an OnPreferenceClickListener that returns true, consuming the click so the named fragment is not launched.
- generateFragmentAllowlist and filterBlockedFragments are package-visible (@VisibleForTesting) and null-safe: a null group returns an empty set or does nothing. The Android 15 commit also adds Robolectric tests in tests/robotests/src/com/android/settings/accounts/AccountTypePreferenceLoaderTest.java. The Android 14 security cherry-pick changes only the source file.
Completeness
- Covers the inflation site in AccountTypePreferenceLoader where an external authenticator's preference XML is inflated, including nested PreferenceGroups.
- The fragment attribute is not cleared; the fix only overrides the click listener. Any later code that replaces the OnPreferenceClickListener on the same preference could undo the block. The material does not show whether such code exists.
- The allowlist is made of the fragments already in the host group before inflation. An external XML that names one of those same fragment classes is still allowed.
- Only android:fragment is addressed. Intent handling in the class is not changed by this commit.
Behavior changes
- Preferences from an authenticator's accountPreferences XML that declare an android:fragment not already in the host screen now do nothing when clicked, instead of opening a fragment. The fix adds no log message.
- Authenticator apps that used android:fragment in their account preferences lose that behavior. The commit comment says these preferences are rendered into Settings and cannot reach their own Fragments, so there is no acceptable usage of android:fragment here.
Per major
- Android 14: same fix: commit 8261e0ade3b4, cherry-picked into android-security-14.0.0_r12 (source only, no test file). The patched region is fully present at android-security-14.0.0_r29.
- Android 15: same fix: commit 2cb9b10ed97b in android-15.0.0_r1 (same source change plus Robolectric tests). The patched region is fully present at android-security-15.0.0_r17.
- Android 16: not affected (not listed by the bulletin). The patched region is present at android-security-16.0.0_r8.
- Android 17: not affected (not listed by the bulletin). The patched region is present at android-security-17.0.0_r1.
Unknowns
- The material does not show fix commits for Android 12, 12L and 13, which the bulletin lists as affected.
- The body of updatePreferenceIntents and its call order relative to filterBlockedFragments are not shown, so it is unknown whether a later listener assignment could override the blocking listener.
- The material does not describe which internal Settings fragment(s) were reachable in the original report.