RESTRICT AUTOMERGE Use consistent calling uid and package in navigateUpTo
Originally, if the caller of navigateUpTo is alive, even the calling
uid is set to the caller who launched the existing destination activity,
the uid from caller process has higher priority to replace the given
calling uid. So this change doesn't modify the existing behavior if
the caller process is valid. Besides, the case of delivering new intent
uses the source record as calling identity too, so the case of starting
new activity should be consistent.
Also forbid attaching null application thread to avoid unexpected state
in process record.
Bug: 144285917
Test: atest ActivityStackTests#testNavigateUpTo
Test: atest CtsSecurityTestCases:ActivityManagerTest# \
testActivityManager_attachNullApplication
Change-Id: I60732f430256d37cb926d08d093581f051c4afed
This commit is contained in:
@@ -7593,7 +7593,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
private final boolean attachApplicationLocked(IApplicationThread thread,
|
||||
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
|
||||
int pid, int callingUid, long startSeq) {
|
||||
|
||||
// Find the application record that is being attached... either via
|
||||
@@ -7974,6 +7974,9 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
|
||||
@Override
|
||||
public final void attachApplication(IApplicationThread thread, long startSeq) {
|
||||
if (thread == null) {
|
||||
throw new SecurityException("Invalid application interface");
|
||||
}
|
||||
synchronized (this) {
|
||||
int callingPid = Binder.getCallingPid();
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
|
||||
@@ -3943,6 +3943,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
|
||||
final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
|
||||
Intent resultData) {
|
||||
if (srec.app == null || srec.app.thread == null) {
|
||||
// Nothing to do if the caller is not attached, because this method should be called
|
||||
// from an alive activity.
|
||||
return false;
|
||||
}
|
||||
final TaskRecord task = srec.getTask();
|
||||
final ArrayList<ActivityRecord> activities = task.mActivities;
|
||||
final int start = activities.indexOf(srec);
|
||||
@@ -3994,14 +3999,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
}
|
||||
|
||||
if (parent != null && foundParentInTask) {
|
||||
final int callingUid = srec.info.applicationInfo.uid;
|
||||
final int parentLaunchMode = parent.info.launchMode;
|
||||
final int destIntentFlags = destIntent.getFlags();
|
||||
if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
|
||||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
|
||||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
|
||||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
|
||||
parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
|
||||
srec.packageName);
|
||||
parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName);
|
||||
} else {
|
||||
try {
|
||||
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
|
||||
@@ -4014,10 +4019,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
.setActivityInfo(aInfo)
|
||||
.setResultTo(parent.appToken)
|
||||
.setCallingPid(-1)
|
||||
.setCallingUid(parent.launchedFromUid)
|
||||
.setCallingPackage(parent.launchedFromPackage)
|
||||
.setCallingUid(callingUid)
|
||||
.setCallingPackage(srec.packageName)
|
||||
.setRealCallingPid(-1)
|
||||
.setRealCallingUid(parent.launchedFromUid)
|
||||
.setRealCallingUid(callingUid)
|
||||
.setComponentSpecified(true)
|
||||
.execute();
|
||||
foundParentInTask = res == ActivityManager.START_SUCCESS;
|
||||
|
||||
@@ -606,6 +606,19 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
assertTrue(listener.changed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNavigateUpTo() {
|
||||
final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
|
||||
final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask)
|
||||
.setUid(firstActivity.getUid() + 1).build();
|
||||
secondActivity.app.thread = null;
|
||||
// This should do nothing from a non-attached caller (app.thread == null).
|
||||
assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */,
|
||||
firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
|
||||
assertFalse(secondActivity.finishing);
|
||||
assertFalse(firstActivity.finishing);
|
||||
}
|
||||
|
||||
private void verifyShouldSleepActivities(boolean focusedStack,
|
||||
boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
|
||||
mSupervisor.mFocusedStack = focusedStack ? mStack : null;
|
||||
|
||||
@@ -192,6 +192,8 @@ public class ActivityTestsBase {
|
||||
aInfo.applicationInfo = new ApplicationInfo();
|
||||
aInfo.applicationInfo.packageName = mComponent.getPackageName();
|
||||
aInfo.applicationInfo.uid = mUid;
|
||||
aInfo.packageName = mComponent.getPackageName();
|
||||
aInfo.name = mComponent.getClassName();
|
||||
aInfo.flags |= mActivityFlags;
|
||||
|
||||
final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
|
||||
|
||||
Reference in New Issue
Block a user