diff options
| author | 2016-05-18 10:54:04 -0700 | |
|---|---|---|
| committer | 2016-05-18 11:51:09 -0700 | |
| commit | 3603bc6e3f73421f59a53ff9f5f9d19bc33074f7 (patch) | |
| tree | 567d60493cda36e7895281355b27b3c55ebac661 | |
| parent | e821f3d032b4cd738a9b61549559b8b76b3ae09e (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.java | 25 |
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); |