From 7d81de038035a6568251abd089c7978ee2cc4e68 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Fri, 12 Aug 2016 18:49:56 -0700 Subject: DO NOT MERGE: Clean up when recycling a pid with a pending launch Fix for accidental launch of a broadcast receiver in an incorrect app instance. Bug: 30202481 Change-Id: I84b74edc29ca3fb88048b44af682ecbeb176b774 (cherry picked from commit a3af5c620727a9c1cd51d7864b3c40bb5de70a40) --- .../android/server/am/ActivityManagerService.java | 23 +++++++++++++++++----- .../java/com/android/server/am/BroadcastQueue.java | 5 +++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 0663720bea6..5a864e13c3b 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -2938,6 +2938,15 @@ public final class ActivityManagerService extends ActivityManagerNative app.removed = false; app.killedByAm = false; synchronized (mPidsSelfLocked) { + ProcessRecord oldApp; + // If there is already an app occupying that pid that hasn't been cleaned up + if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) { + // Clean up anything relating to this pid first + Slog.w(TAG, "Reusing pid " + startResult.pid + + " while app is still mapped to it"); + cleanUpApplicationRecordLocked(oldApp, false, false, -1, + true /*replacingPid*/); + } this.mPidsSelfLocked.put(startResult.pid, app); Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); msg.obj = app; @@ -3745,7 +3754,8 @@ public final class ActivityManagerService extends ActivityManagerNative */ private final void handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart) { - cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); + cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1, + false /*replacingPid*/); if (!restarting) { removeLruProcessLocked(app); } @@ -12589,7 +12599,8 @@ public final class ActivityManagerService extends ActivityManagerNative * a process when running in single process mode. */ private final void cleanUpApplicationRecordLocked(ProcessRecord app, - boolean restarting, boolean allowRestart, int index) { + boolean restarting, boolean allowRestart, int index, boolean replacingPid) { + Slog.d(TAG, "cleanUpApplicationRecordLocked -- " + app.pid); if (index >= 0) { removeLruProcessLocked(app); } @@ -12714,8 +12725,10 @@ public final class ActivityManagerService extends ActivityManagerNative if (!app.persistent || app.isolated) { if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "Removing non-persistent process during cleanup: " + app); - mProcessNames.remove(app.processName, app.uid); - mIsolatedProcesses.remove(app.uid); + if (!replacingPid) { + mProcessNames.remove(app.processName, app.uid); + mIsolatedProcesses.remove(app.uid); + } if (mHeavyWeightProcess == app) { mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, mHeavyWeightProcess.userId, 0)); @@ -16049,7 +16062,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Ignore exceptions. } } - cleanUpApplicationRecordLocked(app, false, true, -1); + cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); mRemovedProcesses.remove(i); if (app.persistent) { diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java index 90b0896dbb4..d83f9c5f038 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/java/com/android/server/am/BroadcastQueue.java @@ -262,6 +262,11 @@ public final class BroadcastQueue { boolean didSomething = false; final BroadcastRecord br = mPendingBroadcast; if (br != null && br.curApp.pid == app.pid) { + if (br.curApp != app) { + Slog.e(TAG, "App mismatch when sending pending broadcast to " + + app.processName + ", intended target is " + br.curApp.processName); + return false; + } try { mPendingBroadcast = null; processCurBroadcastLocked(br, app); -- cgit v1.2.3