Merge "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" into qt-dev

am: 4886935329

Change-Id: Id6cf8e9659255fca002767d86e91d83866305249
This commit is contained in:
Michal Karpinski
2019-04-16 10:32:22 -07:00
committed by android-build-merger
4 changed files with 26 additions and 6 deletions

View File

@@ -29,6 +29,7 @@ import android.content.Intent;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.Process;
import android.os.RemoteCallbackList; import android.os.RemoteCallbackList;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.TransactionTooLargeException; import android.os.TransactionTooLargeException;
@@ -380,8 +381,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
userId = controller.mUserController.getCurrentOrTargetUserId(); userId = controller.mUserController.getCurrentOrTargetUserId();
} }
// temporarily allow receivers and services to open activities from background if the // temporarily allow receivers and services to open activities from background if the
// PendingIntent.send() caller was foreground at the time of sendInner() call // PendingIntent.send() caller was foreground at the time of sendInner() call, unless
final boolean allowTrampoline = uid != callingUid // caller is SYSTEM_UID
final boolean allowTrampoline = uid != callingUid && callingUid != Process.SYSTEM_UID
&& controller.mAtmInternal.isUidForeground(callingUid); && controller.mAtmInternal.isUidForeground(callingUid);
// note: we on purpose don't pass in the information about the PendingIntent's creator, // note: we on purpose don't pass in the information about the PendingIntent's creator,

View File

@@ -971,8 +971,9 @@ class ActivityStarter {
: (realCallingUid == Process.SYSTEM_UID) : (realCallingUid == Process.SYSTEM_UID)
|| realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
if (realCallingUid != callingUid) { if (realCallingUid != callingUid) {
// don't abort if the realCallingUid has a visible window // don't abort if the realCallingUid has a visible window, unless realCallingUid is
if (realCallingUidHasAnyVisibleWindow) { // SYSTEM_UID, in which case it start needs to be explicitly whitelisted
if (realCallingUidHasAnyVisibleWindow && realCallingUid != Process.SYSTEM_UID) {
return false; return false;
} }
// if the realCallingUid is a persistent system process, abort if the IntentSender // if the realCallingUid is a persistent system process, abort if the IntentSender

View File

@@ -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.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; 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.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_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 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. * 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) { boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
return forAllWindows(w -> return forAllWindows(w ->
w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST w.getOwningUid() == callingUid && w.mAttrs.type != TYPE_TOAST
&& w.isVisibleNow(), && w.mAttrs.type != TYPE_APPLICATION_STARTING && w.isVisibleNow(),
true /* traverseTopToBottom */); true /* traverseTopToBottom */);
} }

View File

@@ -17,6 +17,7 @@
package com.android.server.wm; package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; 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_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 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; private static final int FAKE_CALLING_UID = 667;
@Test @Test
public void testIsAnyNonToastWindowVisibleForUid_oneToastOneNonToastBothVisible() { public void testIsAnyNonToastWindowVisibleForUid_oneToastOneAppStartOneNonToastBothVisible() {
final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID); final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID);
final WindowState app = createWindow(null, TYPE_APPLICATION, "app", 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; toastyToast.mHasSurface = true;
app.mHasSurface = true; app.mHasSurface = true;
appStart.mHasSurface = true;
assertTrue(toastyToast.isVisibleNow()); assertTrue(toastyToast.isVisibleNow());
assertTrue(app.isVisibleNow()); assertTrue(app.isVisibleNow());
assertTrue(appStart.isVisibleNow());
assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
} }
@@ -64,6 +69,16 @@ public class RootWindowContainerTests extends WindowTestsBase {
assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID)); 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 @Test
public void testIsAnyNonToastWindowVisibleForUid_aFewNonToastButNoneVisible() { public void testIsAnyNonToastWindowVisibleForUid_aFewNonToastButNoneVisible() {
final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID); final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID);