[RESTRICT AUTOMERGE]Only allow system and same app to apply relinquishTaskIdentity

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
This commit is contained in:
Jeff Chang
2021-09-29 16:49:00 +08:00
parent a14ca941a8
commit cd1f9e72cf

View File

@@ -110,6 +110,7 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Debug; import android.os.Debug;
import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.Trace; import android.os.Trace;
@@ -203,6 +204,11 @@ class TaskRecord extends ConfigurationContainer {
// Do not move the stack as a part of reparenting // Do not move the stack as a part of reparenting
static final int REPARENT_LEAVE_STACK_IN_PLACE = 2; 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}. * The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
*/ */
@@ -869,17 +875,25 @@ class TaskRecord extends ConfigurationContainer {
/** Sets the original intent, and the calling uid and package. */ /** Sets the original intent, and the calling uid and package. */
void setIntent(ActivityRecord r) { void setIntent(ActivityRecord r) {
mCallingUid = r.launchedFromUid; boolean updateIdentity = false;
mCallingPackage = r.launchedFromPackage; if (this.intent == null) {
setIntent(r.intent, r.info); 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); setLockTaskAuth(r);
} }
/** Sets the original intent, _without_ updating the calling uid or package. */ /** Sets the original intent, _without_ updating the calling uid or package. */
private void setIntent(Intent _intent, ActivityInfo info) { private void setIntent(Intent _intent, ActivityInfo info) {
if (intent == null) { if (intent == null) {
mNeverRelinquishIdentity = mNeverRelinquishIdentity = (info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
(info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0;
} else if (mNeverRelinquishIdentity) { } else if (mNeverRelinquishIdentity) {
return; return;
} }
@@ -892,6 +906,7 @@ class TaskRecord extends ConfigurationContainer {
rootAffinity = affinity; rootAffinity = affinity;
} }
effectiveUid = info.applicationInfo.uid; effectiveUid = info.applicationInfo.uid;
mIsEffectivelySystemApp = info.applicationInfo.isSystemApp();
stringName = null; stringName = null;
if (info.targetActivity == null) { if (info.targetActivity == null) {
@@ -1662,12 +1677,12 @@ class TaskRecord extends ConfigurationContainer {
// utility activities. // utility activities.
int activityNdx; int activityNdx;
final int numActivities = mActivities.size(); final int numActivities = mActivities.size();
final boolean relinquish = numActivities != 0 && for (activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
(mActivities.get(0).info.flags & FLAG_RELINQUISH_TASK_IDENTITY) != 0;
for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
++activityNdx) {
final ActivityRecord r = mActivities.get(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 // This will be the top activity for determining taskDescription. Pre-inc to
// overcome initial decrement below. // overcome initial decrement below.
++activityNdx; ++activityNdx;
@@ -1739,15 +1754,27 @@ class TaskRecord extends ConfigurationContainer {
int findEffectiveRootIndex() { int findEffectiveRootIndex() {
int effectiveNdx = 0; int effectiveNdx = 0;
final int topActivityNdx = mActivities.size() - 1; final int topActivityNdx = mActivities.size() - 1;
ActivityRecord root = null;
for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) { for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
final ActivityRecord r = mActivities.get(activityNdx); final ActivityRecord r = mActivities.get(activityNdx);
if (r.finishing) { if (r.finishing) {
continue; 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; break;
} }
effectiveNdx = activityNdx;
root = r;
} }
return effectiveNdx; return effectiveNdx;
} }