From 55af6c5f7094b6be72da46de478ea334a6519543 Mon Sep 17 00:00:00 2001 From: Shunta Sato Date: Wed, 19 Oct 2016 15:58:52 +0900 Subject: [PATCH] Avoid deadlock when installing app Symptom: System crash is occurred by deadlock Root cause: ActivityManagerService's APIs usually hold a lock of itself instance. In this case, four threads tried to take the same lock and it caused deadlock. Following three objects are in a three-cornered deadlocked. - ActivityManagerService's instance - PackageInstallerSession.mLock - PackageManagerService.mPackages Solution: Call checkUidPermission before taking a lock of ActivityManagerService's instance. Fixes: 32425801 Test: manual Author: Kazuki Nakayama Change-Id: I71ce57b1b8f3e0e9ba64b94a7b1f210b702efb6a --- .../java/com/android/server/am/ActiveServices.java | 5 ++--- .../android/server/am/ActivityManagerService.java | 13 ++++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 2bc131fae9058..b4f8f61971f89 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -2810,14 +2810,13 @@ public final class ActiveServices { } List getRunningServiceInfoLocked(int maxNum, int flags, - int callingUid, boolean allowed) { + int callingUid, boolean allowed, boolean canInteractAcrossUsers) { ArrayList res = new ArrayList(); final long ident = Binder.clearCallingIdentity(); try { - if (ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid) - == PERMISSION_GRANTED) { + if (canInteractAcrossUsers) { int[] users = mAm.mUserController.getUsers(); for (int ui=0; ui alls = getServicesLocked(users[ui]); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 67cac981f5997..fb53419246f04 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -17506,12 +17506,15 @@ public class ActivityManagerService extends IActivityManager.Stub public List getServices(int maxNum, int flags) { enforceNotIsolatedCaller("getServices"); - synchronized (this) { - final int callingUid = Binder.getCallingUid(); - final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(), - callingUid); - return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, allowed); + final int callingUid = Binder.getCallingUid(); + final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission( + INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED); + final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(), + callingUid); + synchronized (this) { + return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, + allowed, canInteractAcrossUsers); } }