CVE-2025-0080 AI-generated analysis
platform/frameworks/base, packages/PackageInstaller (app unarchive / restore flow: UnarchiveActivity, UnarchiveFragment)
The fix hardens the PackageInstaller unarchive confirmation UI against overlays in two ways: it adds SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS to UnarchiveActivity's window, and it disables the dialog's Restore button whenever UnarchiveFragment is paused, then re-enables it on resume.
Root cause
UnarchiveActivity displayed the UnarchiveFragment AlertDialog (title built from APP_TITLE/INSTALLER_TITLE, positive button R.string.restore, negative button cancel) without setting SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS on its window. Non-system overlays could therefore be shown over the restore confirmation. The fragment also kept the Restore button enabled even when another window was shown on top of PackageInstaller.
How the fix works
- packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveActivity.java:onCreate calls getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) before super.onCreate(null), so non-system overlay windows are hidden while the unarchive activity is showing. It adds a new static import of WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS.
- packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveFragment.java:onCreateDialog stores the created AlertDialog in a new field, mDialog, instead of returning it directly.
- packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveFragment.java:onStart (new): after super.onStart(), if mDialog != null, it stores ((AlertDialog) mDialog).getButton(DialogInterface.BUTTON_POSITIVE) in a new field, mRestoreButton.
- packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveFragment.java:onPause (new): after super.onPause(), it calls mRestoreButton.setEnabled(false) when the field is non-null, so Restore cannot be triggered while another window is shown on top.
- packages/PackageInstaller/src/com/android/packageinstaller/UnarchiveFragment.java:onResume (new): after super.onResume(), it calls mRestoreButton.setEnabled(true) when the field is non-null.
Completeness
- Covers the UnarchiveActivity window (overlay-hiding flag) and the positive Restore button of UnarchiveFragment (disabled while paused).
- Only the positive button (BUTTON_POSITIVE) is disabled while paused. The negative Cancel button stays enabled, which looks like a deliberate scope choice since Cancel is the non-privileged action.
- SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS hides non-system overlays only (general platform knowledge).
- The fix does not add touch filtering (for example filterTouchesWhenObscured) to the dialog. Protection relies on the window flag plus pause/resume gating.
Behavior changes
- While UnarchiveActivity is visible, non-system overlay windows are hidden.
- The Restore button in the unarchive dialog is disabled whenever the fragment is paused (another window shown on top) and re-enabled on resume.
- No API change is visible in the diff. The commit names CtsPackageUninstallTestCases:ArchiveTest as its test.
Per major
- Android 14: not affected: not listed by the bulletin. At android-security-14.0.0_r29 both patched files (UnarchiveActivity.java, UnarchiveFragment.java) are absent.
- Android 15: same fix: commit 5916a3de10fa in android-security-15.0.0_r6 (cherry-pick of 799842233276351680f47420d8754f381dcbf86f, Change-Id If750c0a613136f3ad3040c544bd70ab428fe5ef2). At android-security-15.0.0_r17, 8/8 lines of the patched region are present.
- Android 16: not affected: not listed by the bulletin. At android-security-16.0.0_r8, 8/8 lines of the patched region are present.
- Android 17: not affected: not listed by the bulletin. At android-security-17.0.0_r1, 8/8 lines of the patched region are present.
Unknowns
- The material does not describe the concrete attack scenario, which overlay type was abused, or what privilege is gained. The bulletin only rates it High / EoP.
- Whether the ArchiveTest CTS coverage includes an overlay regression test is not shown.
- Whether mRestoreButton could remain null in some lifecycle path (for example fragment recreation), which would silently skip the pause gating, is not shown.
- Whether other PackageInstaller confirmation dialogs received equivalent hardening in separate commits is not shown.