From c75587ed5b08c57b7119c424becbf2d80326accb Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 11 Apr 2017 15:37:03 -0700 Subject: [PATCH] Work on issue #36427964: SecurityException: Unable to find app... ...for caller android.app.IApplicationThread Verify, if we don't find the caller on the LRU process list, that it isn't actually on the main list. (And if it is on the main list, we can now recover from that.) Also fix the error message when this fails for startService() to print the correct calling pid. Test: booted and ran Change-Id: I0a81c679bb7e6eb15b854ed4b457d01b386d5dba --- .../java/com/android/server/am/ActiveServices.java | 43 +++++++++---------- .../android/server/am/ActivityManagerService.java | 48 +++++++++++++++++----- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 7dd75df5252a..c77820b4de3a 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -324,7 +324,7 @@ public final class ActiveServices { if (callerApp == null) { throw new SecurityException( "Unable to find app for caller " + caller - + " (pid=" + Binder.getCallingPid() + + " (pid=" + callingPid + ") when starting service " + service); } callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND; @@ -353,29 +353,24 @@ public final class ActiveServices { // If this isn't a direct-to-foreground start, check our ability to kick off an // arbitrary service if (!r.startRequested && !fgRequired) { - final long token = Binder.clearCallingIdentity(); - try { - // Before going further -- if this app is not allowed to start services in the - // background, then at this point we aren't going to let it period. - final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName, - r.appInfo.targetSdkVersion, callingPid, false, false); - if (allowed != ActivityManager.APP_START_MODE_NORMAL) { - Slog.w(TAG, "Background start not allowed: service " - + service + " to " + r.name.flattenToShortString() - + " from pid=" + callingPid + " uid=" + callingUid - + " pkg=" + callingPackage); - if (allowed == ActivityManager.APP_START_MODE_DELAYED) { - // In this case we are silently disabling the app, to disrupt as - // little as possible existing apps. - return null; - } - // This app knows it is in the new model where this operation is not - // allowed, so tell it what has happened. - UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid); - return new ComponentName("?", "app is in background uid " + uidRec); - } - } finally { - Binder.restoreCallingIdentity(token); + // Before going further -- if this app is not allowed to start services in the + // background, then at this point we aren't going to let it period. + final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName, + r.appInfo.targetSdkVersion, callingPid, false, false); + if (allowed != ActivityManager.APP_START_MODE_NORMAL) { + Slog.w(TAG, "Background start not allowed: service " + + service + " to " + r.name.flattenToShortString() + + " from pid=" + callingPid + " uid=" + callingUid + + " pkg=" + callingPackage); + if (allowed == ActivityManager.APP_START_MODE_DELAYED) { + // In this case we are silently disabling the app, to disrupt as + // little as possible existing apps. + return null; + } + // This app knows it is in the new model where this operation is not + // allowed, so tell it what has happened. + UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid); + return new ComponentName("?", "app is in background uid " + uidRec); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 35654d76dee5..8587cfb906d2 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5243,10 +5243,10 @@ public class ActivityManagerService extends IActivityManager.Stub } private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { - IBinder threadBinder = thread.asBinder(); + final IBinder threadBinder = thread.asBinder(); // Find the application record. for (int i=mLruProcesses.size()-1; i>=0; i--) { - ProcessRecord rec = mLruProcesses.get(i); + final ProcessRecord rec = mLruProcesses.get(i); if (rec.thread != null && rec.thread.asBinder() == threadBinder) { return i; } @@ -5261,7 +5261,27 @@ public class ActivityManagerService extends IActivityManager.Stub } int appIndex = getLRURecordIndexForAppLocked(thread); - return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; + if (appIndex >= 0) { + return mLruProcesses.get(appIndex); + } + + // Validation: if it isn't in the LRU list, it shouldn't exist, but let's + // double-check that. + final IBinder threadBinder = thread.asBinder(); + final ArrayMap> pmap = mProcessNames.getMap(); + for (int i = pmap.size()-1; i >= 0; i--) { + final SparseArray procs = pmap.valueAt(i); + for (int j = procs.size()-1; j >= 0; j--) { + final ProcessRecord proc = procs.valueAt(j); + if (proc.thread != null && proc.thread.asBinder() == threadBinder) { + Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: " + + proc); + return proc; + } + } + } + + return null; } final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { @@ -17861,10 +17881,14 @@ public class ActivityManagerService extends IActivityManager.Stub final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); - ComponentName res = mServices.startServiceLocked(caller, service, - resolvedType, id, notification, callingPid, callingUid, - requireForeground, callingPackage, userId); - Binder.restoreCallingIdentity(origId); + ComponentName res; + try { + res = mServices.startServiceLocked(caller, service, + resolvedType, id, notification, callingPid, callingUid, + requireForeground, callingPackage, userId); + } finally { + Binder.restoreCallingIdentity(origId); + } return res; } } @@ -17876,9 +17900,13 @@ public class ActivityManagerService extends IActivityManager.Stub if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "startServiceInPackage: " + service + " type=" + resolvedType); final long origId = Binder.clearCallingIdentity(); - ComponentName res = mServices.startServiceLocked(null, service, - resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId); - Binder.restoreCallingIdentity(origId); + ComponentName res; + try { + res = mServices.startServiceLocked(null, service, + resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId); + } finally { + Binder.restoreCallingIdentity(origId); + } return res; } } -- 2.11.0