From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeff Chang <chengjeff@google.com>
Date: Wed, 29 Sep 2021 16:49:00 +0800
Subject: [PATCH] Only allow system and same app to apply
 relinquishTaskIdentity
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Any malicious application could hijack tasks by
android:relinquishTaskIdentity. This vulnerability can perform UI
spoofing or spy on user’s activities.

This CL limit the usage which only allow system and same app to apply
relinquishTaskIdentity

Bug: 185810717
Test: atest IntentTests
      atest ActivityStarterTests
Change-Id: I55fe8938cd9a0dd7c0268e1cfec89d4e95eee049
(cherry picked from commit cd1f9e72cf9752c9a31e990822ab34ae3d475fec)
Merged-In: I55fe8938cd9a0dd7c0268e1cfec89d4e95eee049
---
 .../com/android/server/am/TaskRecord.java     | 51 ++++++++++++++-----
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 766cee3278ad..6b42918eddb6 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -96,6 +96,7 @@ import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Debug;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -193,6 +194,11 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
     // Do not move the stack as a part of reparenting
     static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
 
+    /**
+     * Used to identify if the activity that is installed from device's system image.
+     */
+    boolean mIsEffectivelySystemApp;
+
     /**
      * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
      */
@@ -788,17 +794,25 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
 
     /** Sets the original intent, and the calling uid and package. */
     void setIntent(ActivityRecord r) {
-        mCallingUid = r.launchedFromUid;
-        mCallingPackage = r.launchedFromPackage;
-        setIntent(r.intent, r.info);
+        boolean updateIdentity = false;
+        if (this.intent == null) {
+            updateIdentity = true;
+        } else if (!mNeverRelinquishIdentity) {
+            updateIdentity = (effectiveUid == Process.SYSTEM_UID || mIsEffectivelySystemApp
+                    || effectiveUid == r.info.applicationInfo.uid);
+        }
+        if (updateIdentity) {
+            mCallingUid = r.launchedFromUid;
+            mCallingPackage = r.launchedFromPackage;
+            setIntent(r.intent, r.info);
+        }
         setLockTaskAuth(r);
     }
 
     /** Sets the original intent, _without_ updating the calling uid or package. */
     private void setIntent(Intent _intent, ActivityInfo info) {
         if (intent == null) {
-            mNeverRelinquishIdentity =
-                    (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
+            mNeverRelinquishIdentity = (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
         } else if (mNeverRelinquishIdentity) {
             return;
         }
@@ -811,6 +825,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
             rootAffinity = affinity;
         }
         effectiveUid = info.applicationInfo.uid;
+        mIsEffectivelySystemApp = info.applicationInfo.isSystemApp();
         stringName = null;
 
         if (info.targetActivity == null) {
@@ -1575,12 +1590,12 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
         // utility activities.
         int activityNdx;
         final int numActivities = mActivities.size();
-        final boolean relinquish = numActivities != 0 &&
-                (mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
-        for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
-                ++activityNdx) {
+        for (activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
             final ActivityRecord r = mActivities.get(activityNdx);
-            if (relinquish && (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
+            if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0
+                    || (r.info.applicationInfo.uid != Process.SYSTEM_UID
+                    && !r.info.applicationInfo.isSystemApp()
+                    && r.info.applicationInfo.uid != effectiveUid)) {
                 // This will be the top activity for determining taskDescription. Pre-inc to
                 // overcome initial decrement below.
                 ++activityNdx;
@@ -1645,15 +1660,27 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
     int findEffectiveRootIndex() {
         int effectiveNdx = 0;
         final int topActivityNdx = mActivities.size() - 1;
+        ActivityRecord root = null;
         for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
             final ActivityRecord r = mActivities.get(activityNdx);
             if (r.finishing) {
                 continue;
             }
-            effectiveNdx = activityNdx;
-            if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
+
+            if (root == null) {
+                // Set this as the candidate root since it isn't finishing.
+                root = r;
+                effectiveNdx = activityNdx;
+            }
+            final int uid = root == r ? effectiveUid : r.info.applicationInfo.uid;
+            if ((root.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0
+                || (root.info.applicationInfo.uid != Process.SYSTEM_UID
+                    && !root.info.applicationInfo.isSystemApp()
+                    && root.info.applicationInfo.uid != uid)) {
                 break;
             }
+            effectiveNdx = activityNdx;
+            root = r;
         }
         return effectiveNdx;
     }
