From 72de4ddb461e132f381aad7386f815581fd2aad5 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Fri, 22 Jul 2016 15:46:37 -0700 Subject: [PATCH] Add installer app check in PM.deletePackage. - Update PM.deletePackage to check if an app trying to delete a package is the same app that installed it. - Update system apps to be orphans to allow silent deletion. This will make sure managed provisioning is not affected. Fixes: 30280938 Change-Id: Ideab5a47eee2a00e7eefa9119112e37c3118783f --- .../server/pm/PackageInstallerService.java | 9 ++------ .../server/pm/PackageManagerService.java | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 6a56fa6e629bd..d25abbf1ff8ac 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -870,13 +870,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { IntentSender statusReceiver, int userId) { final int callingUid = Binder.getCallingUid(); mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall"); - boolean allowSilentUninstall = true; if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) { mAppOps.checkPackage(callingUid, callerPackageName); - final String installerPackageName = mPm.getInstallerPackageName(packageName); - allowSilentUninstall = mPm.isOrphaned(packageName) || - (installerPackageName != null - && installerPackageName.equals(callerPackageName)); } // Check whether the caller is device owner, in which case we do it silently. @@ -887,8 +882,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext, statusReceiver, packageName, isDeviceOwner, userId); - if (allowSilentUninstall && mContext.checkCallingOrSelfPermission( - android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) { + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES) + == PackageManager.PERMISSION_GRANTED) { // Sweet, call straight through! mPm.deletePackage(packageName, adapter.getBinder(), userId, flags); } else if (isDeviceOwner) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 54c36e1113913..b7ae07df00cea 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -8371,6 +8371,10 @@ public class PackageManagerService extends IPackageManager.Stub { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; } + if (isSystemApp(pkg)) { + pkgSetting.isOrphaned = true; + } + ArrayList clientLibPkgs = null; if ((scanFlags & SCAN_CHECK_ONLY) != 0) { @@ -15315,6 +15319,19 @@ public class PackageManagerService extends IPackageManager.Stub { Preconditions.checkNotNull(packageName); Preconditions.checkNotNull(observer); final int uid = Binder.getCallingUid(); + if (uid != Process.SHELL_UID && uid != Process.ROOT_UID && uid != Process.SYSTEM_UID + && uid != getPackageUid(mRequiredInstallerPackage, 0, UserHandle.getUserId(uid)) + && !isOrphaned(packageName) + && !isCallerSameAsInstaller(uid, packageName)) { + try { + final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); + intent.setData(Uri.fromParts("package", packageName, null)); + intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); + observer.onUserActionRequired(intent); + } catch (RemoteException re) { + } + return; + } final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { @@ -15383,6 +15400,12 @@ public class PackageManagerService extends IPackageManager.Stub { }); } + private boolean isCallerSameAsInstaller(int callingUid, String pkgName) { + final int installerPkgUid = getPackageUid(getInstallerPackageName(pkgName), + 0 /* flags */, UserHandle.getUserId(callingUid)); + return installerPkgUid == callingUid; + } + private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { int[] result = EMPTY_INT_ARRAY; for (int userId : userIds) {