summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Winson <chiuwinson@google.com> 2020-04-23 10:45:55 -0700
committer Winson Chiu <chiuwinson@google.com> 2020-05-21 17:17:53 +0000
commit40ca8b51fa90457cc49b91eac00636d1626b3a1b (patch)
treec1bb1f1c8dd6e60ee051adeb8f14fbeea0b176af
parentb1ae5fd44388f4e3c74a8caa690d4a66e9f99f4d (diff)
DO NOT MERGE: Verify INSTALL_PACKAGES permissions when adding installer package
Without this check, any package can set the installer package of another package whose installer has been removed or was never set. This provides access to other privileged actions and is undesired. Bug: 150857253 Test: manual verify with proof of concept in linked bug Test: atest android.appsecurity.cts.PackageSetInstallerTest Change-Id: I2159c357911ff39ffd819054b42f96ae86bc98bc
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java32
1 files changed, 19 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c8175befe179..c84aedc04491 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -15908,20 +15908,26 @@ public class PackageManagerService extends IPackageManager.Stub
// Verify: if target already has an installer package, it must
// be signed with the same cert as the caller.
- if (targetPackageSetting.installerPackageName != null) {
- PackageSetting setting = mSettings.mPackages.get(
- targetPackageSetting.installerPackageName);
- // If the currently set package isn't valid, then it's always
- // okay to change it.
- if (setting != null) {
- if (compareSignatures(callerSignature,
- setting.signatures.mSignatures)
- != PackageManager.SIGNATURE_MATCH) {
- throw new SecurityException(
- "Caller does not have same cert as old installer package "
- + targetPackageSetting.installerPackageName);
- }
+ String targetInstallerPackageName =
+ targetPackageSetting.installerPackageName;
+ PackageSetting targetInstallerPkgSetting = targetInstallerPackageName == null ? null :
+ mSettings.mPackages.get(targetInstallerPackageName);
+
+ if (targetInstallerPkgSetting != null) {
+ if (compareSignatures(callerSignature,
+ targetInstallerPkgSetting.signatures.mSignatures)
+ != PackageManager.SIGNATURE_MATCH) {
+ throw new SecurityException(
+ "Caller does not have same cert as old installer package "
+ + targetInstallerPackageName);
}
+ } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
+ != PackageManager.PERMISSION_GRANTED) {
+ // This is probably an attempt to exploit vulnerability b/150857253 of taking
+ // privileged installer permissions when the installer has been uninstalled or
+ // was never set.
+ EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
+ return;
}
// Okay!