Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55af6c5f authored by Shunta Sato's avatar Shunta Sato Committed by Wale Ogunwale
Browse files

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 <kazuki.x.nakayama@sonymobile.com>
Change-Id: I71ce57b1b8f3e0e9ba64b94a7b1f210b702efb6a
parent 9ac082f8
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -2810,14 +2810,13 @@ public final class ActiveServices {
    }

    List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, int flags,
        int callingUid, boolean allowed) {
        int callingUid, boolean allowed, boolean canInteractAcrossUsers) {
        ArrayList<ActivityManager.RunningServiceInfo> res
                = new ArrayList<ActivityManager.RunningServiceInfo>();

        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<users.length && res.size() < maxNum; ui++) {
                    ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(users[ui]);
+8 −5
Original line number Diff line number Diff line
@@ -17506,12 +17506,15 @@ public class ActivityManagerService extends IActivityManager.Stub
    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
            int flags) {
        enforceNotIsolatedCaller("getServices");
        synchronized (this) {
        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);
            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, allowed);
        synchronized (this) {
            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
                allowed, canInteractAcrossUsers);
        }
    }