CVE-2024-49722 AI-generated analysis
platform/frameworks/base, packages/SettingsLib users (EditUserPhotoController avatar picker launch); plus platform/build/release aconfig flag value
Makes SettingsLib's EditUserPhotoController launch the avatar picker with an explicit component (package and class from new config resources) instead of an implicit AVATAR_PICKER_ACTION intent when the avatarSync flag path is taken, and then removes the guarding fixAvatarCrossUserLeak flag so the fix is unconditional.
Root cause
In EditUserPhotoController.showAvatarPicker, when Flags.avatarSync() was true, the code built an Intent for AVATAR_PICKER_ACTION with CATEGORY_DEFAULT, added EXTRA_IS_USER_NEW and EXTRA_FILE_AUTHORITY, and called mActivityStarter.startActivityForResult without restricting the target. Only the non-avatarSync else branch constrained the intent (intent.setPackage to the calling app's own package). The implicit intent could therefore resolve to a component other than the intended avatar picker. The result was handled by onActivityResult (REQUEST_CODE_PICK_AVATAR), which acts on EXTRA_DEFAULT_ICON_TINT_COLOR or on data.getData() via onPhotoCropped. The flag name (fix_avatar_cross_user_leak) and the code comment tie the change to b/341688848, an avatar cross-user leak.
How the fix works
- Commit 8cba0e8bcfc2 (frameworks/base): packages/SettingsLib/res/values/config.xml adds two non-translatable strings, config_avatar_picker_package = com.android.avatarpicker and config_avatar_picker_class = com.android.avatarpicker.ui.AvatarPickerActivity.
- Commit 8cba0e8bcfc2 (frameworks/base): EditUserPhotoController.java imports com.android.settingslib.R. In showAvatarPicker, inside the Flags.avatarSync() branch and under a new Flags.fixAvatarCrossUserLeak() guard, it reads the two config strings via mActivity.getString and calls intent.setClassName(packageName, className). This makes the intent explicit before startActivityForResult.
- Commit a17efb2eadc0 (build/release): adds aconfig/trunk_staging/android.multiuser/fix_avatar_cross_user_leak_flag_values.textproto, which sets android.multiuser.fix_avatar_cross_user_leak to ENABLED (READ_WRITE) in trunk staging.
- Commit 2b4d662a462c (frameworks/base): removes the Flags.fixAvatarCrossUserLeak() guard, so intent.setClassName(...) runs unconditionally whenever Flags.avatarSync() is true. The commit message says the flag was missing on the security branch and caused a build failure. This unflagged code is what android-security-15.0.0_r17 contains, and the textproto flag-value file is absent in that tag.
Completeness
- The fix covers only the Flags.avatarSync() branch of showAvatarPicker. The else branch already restricted the intent with setPackage to the app's own package and is unchanged.
- The fix pins the target to a package/class set in resources. It adds no validation of the result received in onActivityResult (EXTRA_DEFAULT_ICON_TINT_COLOR, data.getData()) and relies on the explicit component to ensure the result comes from the intended picker.
- The fix depends on the config strings matching the avatar picker actually shipped on the device. The material shows no runtime check that the configured component exists.
- After 2b4d662a462c the fix is unconditional (not gated by fixAvatarCrossUserLeak), but it still applies only when android.multiuser.Flags.avatarSync() is enabled.
Behavior changes
- With avatarSync enabled, the avatar picker intent now resolves only to com.android.avatarpicker/com.android.avatarpicker.ui.AvatarPickerActivity (or whatever overlaid config strings specify). Other activities matching AVATAR_PICKER_ACTION can no longer handle it.
- If the configured component is not present on the device, startActivityForResult with an explicit component would fail with ActivityNotFoundException rather than resolving to another handler (general platform knowledge).
- Two new SettingsLib string resources (config_avatar_picker_package, config_avatar_picker_class) become values that OEMs can override.
Per major
- Android 14: not affected per the bulletin. The material reports the project as not present in Android 14 security tags and does not show the state of EditUserPhotoController in 14.
- Android 15: same fix: 8cba0e8bcfc2 (flagged fix + config strings) and 2b4d662a462c (flag removal) in frameworks/base at android-security-15.0.0_r5, plus a17efb2eadc0 in build/release. At android-security-15.0.0_r17 the code contains the unflagged setClassName fix and the textproto flag-value file is absent.
- Android 16: not affected (not listed by the bulletin). The state at android-security-16.0.0_r8 is not shown in the material.
- Android 17: not affected (not listed by the bulletin). The state at android-security-17.0.0_r1 is not shown in the material.
Unknowns
- Whether Android 14, 16 or 17 security tags contain the setClassName fix or the avatarSync branch at all (the material gives no frameworks/base state for those majors).
- The exact mechanism of the cross-user leak (which data crossed users) is not shown beyond the implicit intent and the activity result handling.
- Whether the avatarSync flag is enabled by default on affected Android 15 builds.
- Which code paths call showAvatarPicker.
- Why the trunk_staging flag-value file is absent at android-security-15.0.0_r17.