summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Amith Yamasani <yamasani@google.com> 2016-05-18 10:54:04 -0700
committer Amith Yamasani <yamasani@google.com> 2016-05-18 11:51:09 -0700
commit3603bc6e3f73421f59a53ff9f5f9d19bc33074f7 (patch)
tree567d60493cda36e7895281355b27b3c55ebac661
parente821f3d032b4cd738a9b61549559b8b76b3ae09e (diff)
Fix a deadlock in system server
Don't call into DPMS with PackageManager lock held. Doh! Bug: 28828415 Change-Id: I08437d849236374acc0d804fe31aba703af385ba
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java25
1 files changed, 15 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 488645dd6558..35bcaa98bd64 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17550,21 +17550,26 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
throw new IllegalArgumentException(
"Unknown component: " + packageName + "/" + className);
}
- // Don't allow other apps to disable an active profile owner
- if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
- final DevicePolicyManagerInternal dpmi = LocalServices
- .getService(DevicePolicyManagerInternal.class);
- if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
- throw new SecurityException("Cannot disable a device owner or a profile owner");
- }
- }
- // Allow root and verify that userId is not being specified by a different user
- if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
+ }
+
+ // Limit who can change which apps
+ if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
+ // Don't allow apps that don't have permission to modify other apps
+ if (!allowedByPermission) {
throw new SecurityException(
"Permission Denial: attempt to change component state from pid="
+ Binder.getCallingPid()
+ ", uid=" + uid + ", package uid=" + pkgSetting.appId);
}
+ // Don't allow changing profile and device owners. Calling into DPMS, so no locking.
+ final DevicePolicyManagerInternal dpmi = LocalServices
+ .getService(DevicePolicyManagerInternal.class);
+ if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
+ throw new SecurityException("Cannot disable a device owner or a profile owner");
+ }
+ }
+
+ synchronized (mPackages) {
if (uid == Process.SHELL_UID) {
// Shell can only change whole packages between ENABLED and DISABLED_USER states
int oldState = pkgSetting.getEnabled(userId);