diff options
author | 2025-01-06 17:44:44 -0800 | |
---|---|---|
committer | 2025-01-08 11:48:56 -0800 | |
commit | ff21533e7386987fe668e9d4cee20dc2d6b99add (patch) | |
tree | 41a354a90ef0da90a2b4058b5107b5f85c1c52ac | |
parent | d6b3bdf805b44d7d1b27be92d252d600b2e241a2 (diff) |
Look for the installer in all users if DELETE_ALL_USERS is requested
If a caller passes the DELETE_ALL_USERS flag, search for the installer
app in every user, since the uninstall request may initiate from a user
where the package is not installed.
For example, if an app is installed only on user10, and a caller on
user0 is initiating the uninstall (to uninstall from all users),
looking for for the installer package* only on the initiating user
(i.e user 0) will lead to an exception. Thus, loop through all users to
find the installer
(*) We search for the installer to determine if the caller pkg is also
the installer pkg, to allow silent uninstall
Bug: 384544054
Test: TBD
Flag: EXEMPT. Bug fix only
Change-Id: Ibc893fbf32bcef0601cf57cb798f582635ab00c7
-rw-r--r-- | services/core/java/com/android/server/pm/DeletePackageHelper.java | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index f6e518a4fed7..90adb6683496 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -729,10 +729,13 @@ final class DeletePackageHelper { final String internalPackageName = snapshot.resolveInternalPackageName(packageName, versionCode); + final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; + final int[] users = deleteAllUsers ? mUserManagerInternal.getUserIds() : new int[]{userId}; + if (!isOrphaned(snapshot, internalPackageName) && !allowSilentUninstall - && !isCallerAllowedToSilentlyUninstall( - snapshot, callingUid, internalPackageName, userId)) { + && !isCallerAllowedToSilentlyUninstall(snapshot, callingUid, internalPackageName, + users)) { mPm.mHandler.post(() -> { try { final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); @@ -751,8 +754,7 @@ final class DeletePackageHelper { }); return; } - final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; - final int[] users = deleteAllUsers ? mUserManagerInternal.getUserIds() : new int[]{userId}; + if (UserHandle.getUserId(callingUid) != userId || (deleteAllUsers && users.length > 1)) { mPm.mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, @@ -916,16 +918,24 @@ final class DeletePackageHelper { } private boolean isCallerAllowedToSilentlyUninstall(@NonNull Computer snapshot, int callingUid, - String pkgName, int userId) { + String pkgName, int[] targetUserIds) { if (PackageManagerServiceUtils.isRootOrShell(callingUid) || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { return true; } final int callingUserId = UserHandle.getUserId(callingUid); + // If the caller installed the pkgName, then allow it to silently uninstall. - if (callingUid == snapshot.getPackageUid( - snapshot.getInstallerPackageName(pkgName, userId), 0, callingUserId)) { - return true; + for (int user : targetUserIds) { + try { + if (callingUid == snapshot.getPackageUid( + snapshot.getInstallerPackageName(pkgName, user), 0, callingUserId)) { + return true; + } + } catch (Exception ignored) { + // The app to be uninstalled (`pkgName`) is not installed on this `user`. Continue + // looking for the installerPkgName in the next user + } } // Allow package verifier to silently uninstall. |