Don't allow PI-based starts and trampolines when sender
is SYSTEM_UID and it happens to pass foregroundness check at the time of sending It could lead to abuses like directing the user to Settings app and then giving a PI through any API, so that app could open activity/trampoline due to Settings app (SYSTEM_UID) being fg. PI-based starts where sender is SYSTEM_UID will no longer be supported based on foregroundness check. Any such starts need to now be explicitly whitelisted (see b/124858756). Also, ignore windows of type TYPE_APPLICATION_STARTING in isAnyNonToastWindowVisibleForUid() check. Bug: 129563343 Test: atest WmTests:ActivityStarterTests Test: atest BackgroundActivityLaunchTest Test: atest CtsActivityManagerDeviceTestCases:ActivityStarterTests Test: atest WmTests:RootWindowContainerTests Change-Id: I563f71f0b1c7922d8c675d2e4feed909f43446be
This commit is contained in:
@@ -29,6 +29,7 @@ import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.TransactionTooLargeException;
|
||||
@@ -380,8 +381,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
|
||||
userId = controller.mUserController.getCurrentOrTargetUserId();
|
||||
}
|
||||
// temporarily allow receivers and services to open activities from background if the
|
||||
// PendingIntent.send() caller was foreground at the time of sendInner() call
|
||||
final boolean allowTrampoline = uid != callingUid
|
||||
// PendingIntent.send() caller was foreground at the time of sendInner() call, unless
|
||||
// caller is SYSTEM_UID
|
||||
final boolean allowTrampoline = uid != callingUid && callingUid != Process.SYSTEM_UID
|
||||
&& controller.mAtmInternal.isUidForeground(callingUid);
|
||||
|
||||
// note: we on purpose don't pass in the information about the PendingIntent's creator,
|
||||
|
||||
@@ -971,8 +971,9 @@ class ActivityStarter {
|
||||
: (realCallingUid == Process.SYSTEM_UID)
|
||||
|| realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
|
||||
if (realCallingUid != callingUid) {
|
||||
// don't abort if the realCallingUid has a visible window
|
||||
if (realCallingUidHasAnyVisibleWindow) {
|
||||
// don't abort if the realCallingUid has a visible window, unless realCallingUid is
|
||||
// SYSTEM_UID, in which case it start needs to be explicitly whitelisted
|
||||
if (realCallingUidHasAnyVisibleWindow && realCallingUid != Process.SYSTEM_UID) {
|
||||
return false;
|
||||
}
|
||||
// if the realCallingUid is a persistent system process, abort if the IntentSender
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
|
||||
@@ -312,11 +313,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
|
||||
|
||||
/**
|
||||
* Returns true if the callingUid has any non-toast window currently visible to the user.
|
||||
* Also ignores TYPE_APPLICATION_STARTING, since those windows don't belong to apps.
|
||||
*/
|
||||
boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
|
||||
return forAllWindows(w ->
|
||||
w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST
|
||||
&& w.isVisibleNow(),
|
||||
&& w.mAttrs.type != TYPE_APPLICATION_STARTING && w.isVisibleNow(),
|
||||
true /* traverseTopToBottom */);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
|
||||
|
||||
@@ -44,14 +45,18 @@ public class RootWindowContainerTests extends WindowTestsBase {
|
||||
private static final int FAKE_CALLING_UID = 667;
|
||||
|
||||
@Test
|
||||
public void testIsAnyNonToastWindowVisibleForUid_oneToastOneNonToastBothVisible() {
|
||||
public void testIsAnyNonToastWindowVisibleForUid_oneToastOneAppStartOneNonToastBothVisible() {
|
||||
final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID);
|
||||
final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID);
|
||||
final WindowState appStart = createWindow(null, TYPE_APPLICATION_STARTING, "appStarting",
|
||||
FAKE_CALLING_UID);
|
||||
toastyToast.mHasSurface = true;
|
||||
app.mHasSurface = true;
|
||||
appStart.mHasSurface = true;
|
||||
|
||||
assertTrue(toastyToast.isVisibleNow());
|
||||
assertTrue(app.isVisibleNow());
|
||||
assertTrue(appStart.isVisibleNow());
|
||||
assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
|
||||
}
|
||||
|
||||
@@ -64,6 +69,16 @@ public class RootWindowContainerTests extends WindowTestsBase {
|
||||
assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAnyNonToastWindowVisibleForUid_onlyAppStartingVisible() {
|
||||
final WindowState appStart = createWindow(null, TYPE_APPLICATION_STARTING, "appStarting",
|
||||
FAKE_CALLING_UID);
|
||||
appStart.mHasSurface = true;
|
||||
|
||||
assertTrue(appStart.isVisibleNow());
|
||||
assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAnyNonToastWindowVisibleForUid_aFewNonToastButNoneVisible() {
|
||||
final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID);
|
||||
|
||||
Reference in New Issue
Block a user