summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sumedh Sen <sumedhsen@google.com> 2025-01-06 17:44:44 -0800
committer Sumedh Sen <sumedhsen@google.com> 2025-01-08 11:48:56 -0800
commitff21533e7386987fe668e9d4cee20dc2d6b99add (patch)
tree41a354a90ef0da90a2b4058b5107b5f85c1c52ac
parentd6b3bdf805b44d7d1b27be92d252d600b2e241a2 (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.java26
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.