diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 3fa5efcaf0bdf..a16e659610135 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -100,7 +100,6 @@ import com.android.internal.app.AssistUtils; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.common.ProtoLog; -import com.android.internal.util.FrameworkStatsLog; import com.android.server.LocalServices; import com.android.server.Watchdog; import com.android.server.pm.KnownPackages; @@ -491,46 +490,13 @@ class ActivityClientController extends IActivityClientController.Stub { finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY || (finishWithRootActivity && r == rootR)) { - ActivityRecord topActivity = - r.getTask().getTopNonFinishingActivity(); - boolean passesAsmChecks = topActivity != null - && topActivity.getUid() == r.getUid(); - if (!passesAsmChecks) { - Slog.i(TAG, "Finishing task from background. r: " + r); - FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, - /* caller_uid */ - r.getUid(), - /* caller_activity_class_name */ - r.info.name, - /* target_task_top_activity_uid */ - topActivity == null ? -1 : topActivity.getUid(), - /* target_task_top_activity_class_name */ - topActivity == null ? null : topActivity.info.name, - /* target_task_is_different */ - false, - /* target_activity_uid */ - -1, - /* target_activity_class_name */ - null, - /* target_intent_action */ - null, - /* target_intent_flags */ - 0, - /* action */ - FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__FINISH_TASK, - /* version */ - 1, - /* multi_window */ - false - ); - } // If requested, remove the task that is associated to this activity only if it // was the root activity in the task. The result code and data is ignored // because we don't support returning them across task boundaries. Also, to // keep backwards compatibility we remove the task from recents when finishing // task with root activity. mTaskSupervisor.removeTask(tr, false /*killProcess*/, - finishWithRootActivity, "finish-activity"); + finishWithRootActivity, "finish-activity", r.getUid(), r.info.name); res = true; // Explicitly dismissing the activity so reset its relaunch flag. r.mRelaunchReason = RELAUNCH_REASON_NONE; diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 42da2a5e17a8c..0610a2b83481f 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -140,6 +140,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.ReferrerIntent; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService; @@ -1590,11 +1591,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { * @return Returns true if the given task was found and removed. */ boolean removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents, - String reason) { + String reason, int callingUid) { final Task task = mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_OR_RECENT_TASKS); if (task != null) { - removeTask(task, killProcess, removeFromRecents, reason); + removeTask(task, killProcess, removeFromRecents, reason, callingUid, null); return true; } Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); @@ -1602,10 +1603,52 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) { + removeTask(task, killProcess, removeFromRecents, reason, SYSTEM_UID, null); + } + + void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason, + int callingUid, String callerActivityClassName) { if (task.mInRemoveTask) { // Prevent recursion. return; } + // We may have already checked that the callingUid has additional clearTask privileges, and + // cleared the calling identify. If so, we infer we do not need further restrictions here. + // TODO(b/263368846) Move to live with the rest of the ASM logic. + if (callingUid != SYSTEM_UID) { + ActivityRecord topActivity = task.getTopNonFinishingActivity(); + boolean passesAsmChecks = topActivity != null + && topActivity.getUid() == callingUid; + if (!passesAsmChecks) { + Slog.i(TAG, "Finishing task from background. t: " + task); + FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, + /* caller_uid */ + callingUid, + /* caller_activity_class_name */ + callerActivityClassName, + /* target_task_top_activity_uid */ + topActivity == null ? -1 : topActivity.getUid(), + /* target_task_top_activity_class_name */ + topActivity == null ? null : topActivity.info.name, + /* target_task_is_different */ + false, + /* target_activity_uid */ + -1, + /* target_activity_class_name */ + null, + /* target_intent_action */ + null, + /* target_intent_flags */ + 0, + /* action */ + FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__FINISH_TASK, + /* version */ + 1, + /* multi_window */ + false + ); + } + } task.mTransitionController.requestCloseTransitionIfNeeded(task); task.mInRemoveTask = true; try { @@ -1728,7 +1771,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Task was trimmed from the recent tasks list -- remove the active task record as well // since the user won't really be able to go back to it removeTaskById(task.mTaskId, killProcess, false /* removeFromRecents */, - "recent-task-trimmed"); + "recent-task-trimmed", SYSTEM_UID); } task.removedFromRecents(); } diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java index b160af6a3e11f..7bd8c538351d4 100644 --- a/services/core/java/com/android/server/wm/AppTaskImpl.java +++ b/services/core/java/com/android/server/wm/AppTaskImpl.java @@ -72,15 +72,16 @@ class AppTaskImpl extends IAppTask.Stub { checkCallerOrSystemOrRoot(); synchronized (mService.mGlobalLock) { - final long origId = Binder.clearCallingIdentity(); + int origCallingUid = Binder.getCallingUid(); + final long callingIdentity = Binder.clearCallingIdentity(); try { // We remove the task from recents to preserve backwards if (!mService.mTaskSupervisor.removeTaskById(mTaskId, false, - REMOVE_FROM_RECENTS, "finish-and-remove-task")) { + REMOVE_FROM_RECENTS, "finish-and-remove-task", origCallingUid)) { throw new IllegalArgumentException("Unable to find task ID " + mTaskId); } } finally { - Binder.restoreCallingIdentity(origId); + Binder.restoreCallingIdentity(callingIdentity); } } }