CVE-2026-0008 AI-generated analysis
platform/packages/apps/Settings, biometrics face enrollment (FaceEnroll trampoline activity)
FaceEnroll in Settings now strips the MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE extra (alongside Intent.EXTRA_USER_ID) from the forwarded intent when the activity was launched by a package other than Settings itself.
Root cause
FaceEnroll.onCreate builds nextIntent for the real enrollment activity and, per its own comment, includes any existing extras from the current intent. Before the fix, the only extra removed for launches from an external package (launchedFromProvider() != packageName) was Intent.EXTRA_USER_ID. The EXTRA_ENROLL_AFTER_FACE extra, which the updated test populates with a PendingIntent, was forwarded unchanged, so an external caller could pass that key into Settings' downstream enrollment activity.
How the fix works
- src/com/android/settings/biometrics/face/FaceEnroll.kt:onCreate: inside the existing block guarded by `if (launchedFromProvider() != packageName)`, add `nextIntent.removeExtra(EXTRA_ENROLL_AFTER_FACE)` next to the existing `nextIntent.removeExtra(Intent.EXTRA_USER_ID)`; add the import of com.android.settings.biometrics.MultiBiometricEnrollHelper.EXTRA_ENROLL_AFTER_FACE. The remaining hunks (class declaration spacing, comment reflow, trailing commas, onActivityResult condition formatting) are formatting only.
- tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollTest.kt: the test intent now also carries EXTRA_ENROLL_AFTER_FACE as a PendingIntent; the internal-launch test expects 3 extras including EXTRA_ENROLL_AFTER_FACE, and the renamed external-launch test (testFinishAndLaunchDefaultActivity_fromExternal_dropUserAndDropEnrollAfterFace) asserts both EXTRA_USER_ID and EXTRA_ENROLL_AFTER_FACE are absent and only the generic test extra survives. The mockito whenever import also switches to org.mockito.kotlin.
Completeness
- Covers the single forwarding point in FaceEnroll.onCreate for callers whose launchedFromPackage differs from Settings' own package name.
- The approach remains a denylist: all other extras from the incoming intent are still copied into nextIntent; only EXTRA_USER_ID and EXTRA_ENROLL_AFTER_FACE are removed. Any other extra that downstream enrollment activities treat as trusted is not addressed by this change (none is shown in the material).
- Launches where launchedFromPackage equals Settings' package keep the extra, by design.
- The downstream consumer of EXTRA_ENROLL_AFTER_FACE is not in the material, so whether it performs its own caller validation is unknown.
Behavior changes
- For externally launched FaceEnroll, the EXTRA_ENROLL_AFTER_FACE extra is silently dropped before the real enrollment activity starts; the diff adds no error or log for the drop.
- No change for launches originating from Settings itself.
Per major
- Android 14: not affected per the bulletin; code absent (FaceEnroll.kt and FaceEnrollTest.kt do not exist at android-security-14.0.0_r29)
- Android 15: not affected per the bulletin; code absent (FaceEnroll.kt and FaceEnrollTest.kt do not exist at android-security-15.0.0_r17)
- Android 16: same fix: commit 059c9678eebe in android-security-16.0.0_r4 (cherry-pick of 7ac22f2eae5d); at android-security-16.0.0_r8, 7/8 lines of the patched region are present and the EXTRA_ENROLL_AFTER_FACE import is visible in the code context
- Android 17: not affected per the bulletin (Android 17 not listed); at android-security-17.0.0_r1, 7/8 lines of the patched region are present
Unknowns
- How the downstream enrollment flow consumes EXTRA_ENROLL_AFTER_FACE (the PendingIntent) and what privilege it is sent with; not in the material.
- Whether FaceEnroll is exported or protected by a permission in the manifest.
- Whether device or feature conditions (for example face hardware support) gate reaching FaceEnroll.
- Which single line differs at android-security-16.0.0_r8 and android-security-17.0.0_r1 (7/8 lines present).
- Why the bulletin/OSV list 17-next while the per-major facts treat Android 17 as not listed.