Clear out top activities not matching launched uid in task
This change is a continuation of ag/20482146. If we have task1 with activities A1,B1, a task2 in the foreground could launch A2 with the NEWTASK flag, and affinity for A1 - causing an activity sandwich we wish to prevent. Hence, we clear out all activities not matching A's UID when A2 is launched with NEW_TASK. Test: atest ActivitySecurityModelTest Test: manually tested on device Bug: 248045984 Change-Id: Ia90b197aa7d41f91a7f8cc51b572cd344619c6ad
This commit is contained in:
@@ -2080,6 +2080,7 @@ class ActivityStarter {
|
||||
reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);
|
||||
|
||||
if (mAddingToTask) {
|
||||
clearTopIfNeeded(targetTask, mCallingUid, mStartActivity.getUid(), mLaunchFlags);
|
||||
return START_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -2111,6 +2112,55 @@ class ActivityStarter {
|
||||
return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the top activity uid does not match the launched activity, and the launch was not
|
||||
* requested from the top uid, we want to clear out all non matching activities to prevent the
|
||||
* top activity being sandwiched.
|
||||
*/
|
||||
private void clearTopIfNeeded(@NonNull Task targetTask, int callingUid, int startingUid,
|
||||
int launchFlags) {
|
||||
if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) != FLAG_ACTIVITY_NEW_TASK) {
|
||||
// Launch is from the same task, so must be a top or privileged UID
|
||||
return;
|
||||
}
|
||||
|
||||
ActivityRecord targetTaskTop = targetTask.getTopNonFinishingActivity();
|
||||
if (targetTaskTop != null && targetTaskTop.getUid() != startingUid) {
|
||||
boolean shouldBlockActivityStart = ActivitySecurityModelFeatureFlags
|
||||
.shouldBlockActivityStart(callingUid);
|
||||
int[] finishCount = new int[0];
|
||||
if (shouldBlockActivityStart) {
|
||||
ActivityRecord activity = targetTask.getActivity(
|
||||
ar -> !ar.finishing && ar.isUid(startingUid));
|
||||
|
||||
if (activity == null) {
|
||||
// mStartActivity is not in task, so clear everything
|
||||
activity = mStartActivity;
|
||||
}
|
||||
|
||||
finishCount = new int[1];
|
||||
if (activity != null) {
|
||||
targetTask.performClearTop(activity, launchFlags, finishCount);
|
||||
}
|
||||
|
||||
if (finishCount[0] > 0) {
|
||||
Slog.w(TAG, "Clearing top n: " + finishCount[0] + " activities from task t: "
|
||||
+ targetTask + " not matching top uid: " + callingUid);
|
||||
}
|
||||
}
|
||||
|
||||
if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)
|
||||
&& (!shouldBlockActivityStart || finishCount[0] > 0)) {
|
||||
UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
|
||||
(shouldBlockActivityStart
|
||||
? "Top activities cleared by "
|
||||
: "Top activities would be cleared by ")
|
||||
+ ActivitySecurityModelFeatureFlags.DOC_LINK,
|
||||
Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the activity being launched is the same as the one currently at the top and it
|
||||
* should only be launched once.
|
||||
|
||||
Reference in New Issue
Block a user