From d582aff2fc1bf9fcaacb0e7696229df2c1a56b9c Mon Sep 17 00:00:00 2001 From: Hani Kazmi Date: Wed, 6 Jul 2022 16:13:19 +0000 Subject: [PATCH] Add logging for activity starts to be blocked as part of go/activity-security Adds logs for activity starts which don't match the following rules: 1. Only the top activity on a task can start activities on that task 2. Only the top activity on the top task can create new (top) tasks These logs will be used to determine which valid use cases may be blocked by the ASM project in the future. Scenarios which will emit a log: Here, B1 is com.android.messaging.ui.conversationlist.ConversationListActivity 1. A1 launches B1, then A1 launches A2 on top: activity_blocked { caller_uid: 10111 caller_activity_class_name: "com.hanikazmi.activitysecuritymodeltasks.A1" target_task_top_activity_uid: 10078 target_task_top_activity_class_name: "com.android.messaging.ui.conversationlist.ConversationListActivity" target_task_is_different: false target_activity_uid: 10111 target_activity_class_name: "com.hanikazmi.activitysecuritymodeltasks.A2" target_intent_action: "" target_intent_flags: 0 } 2. A1 launches B1, then launches A2 into a new task: activity_blocked { caller_uid: 10111 caller_activity_class_name: "com.hanikazmi.activitysecuritymodeltasks.A1" target_task_top_activity_uid: -1 target_task_top_activity_class_name: "" target_task_is_different: true target_activity_uid: 10111 target_activity_class_name: "com.hanikazmi.activitysecuritymodeltasks.A2" target_intent_action: "" target_intent_flags: 402653184 } 3. A1 finishes itself, then launches A2 4. A1 launching B1 into a new task, then laucnhing B1 again (recycling) 5. A1 launches B1 on top of itself, Then A2 in Task 2 launches A1 again (recycling) Scenarios verified to not log: 1. A1 launching A2 on top of itself 2. A1 launching A2 into a new task 3. A1 launching B1 into a new task 4. A1 launches A2, then finishes itself Test: statsd_testdrive 494 Test: Manually tested above scenarios and viewed logs Bug: 229747522 Change-Id: I5228cd9afbc1567bb5e3d245fa7f2701bf2a78d3 Merged-In: I5228cd9afbc1567bb5e3d245fa7f2701bf2a78d3 --- .../android/server/wm/ActivityStarter.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 99b34c78597cc..ef2baa7d02fc8 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -131,6 +131,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.internal.protolog.common.ProtoLog; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.am.PendingIntentRecord; import com.android.server.pm.InstantAppResolver; import com.android.server.power.ShutdownCheckPoints; @@ -2100,6 +2101,49 @@ class ActivityStarter { } } + // Log activity starts which violate one of the following rules of the + // activity security model (ASM): + // 1. Only the top activity on a task can start activities on that task + // 2. Only the top activity on the top task can create new (top) tasks + // We don't currently block, but these checks may later become blocks + // TODO(b/236234252): Shift to BackgroundActivityStartController once + // class is ready + if (mSourceRecord != null) { + int callerUid = mSourceRecord.getUid(); + ActivityRecord targetTopActivity = + targetTask != null ? targetTask.getTopNonFinishingActivity() : null; + boolean passesAsmChecks = newTask + ? mService.mVisibleActivityProcessTracker.hasResumedActivity(callerUid) + : targetTopActivity != null && targetTopActivity.getUid() == callerUid; + + if (!passesAsmChecks) { + Slog.i(TAG, "Launching r: " + r + + " from background: " + mSourceRecord + + ". New task: " + newTask); + boolean newOrEmptyTask = newTask || (targetTopActivity == null); + FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, + /* caller_uid */ + callerUid, + /* caller_activity_class_name */ + mSourceRecord.info.name, + /* target_task_top_activity_uid */ + newOrEmptyTask ? -1 : targetTopActivity.getUid(), + /* target_task_top_activity_class_name */ + newOrEmptyTask ? null : targetTopActivity.info.name, + /* target_task_is_different */ + newTask || !mSourceRecord.getTask().equals(targetTask), + /* target_activity_uid */ + r.getUid(), + /* target_activity_class_name */ + r.info.name, + /* target_intent_action */ + r.intent.getAction(), + /* target_intent_flags */ + r.intent.getFlags() + ); + } + } + return START_SUCCESS; }