summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Achim Thesmann <achim@google.com> 2023-12-22 03:48:58 +0000
committer Achim Thesmann <achim@google.com> 2024-01-04 01:47:27 +0000
commit2e76468c158ddecbf22ab33c8f525b0e79382ca1 (patch)
tree3cb6f080d09175255c19832cf4b0108af32403a9
parent62acf9ae3a06460c41a2856922ce1076ed11d52f (diff)
Always prefer creator over sender to log BalAllowed
Historically in some cases we logged BAL_ALLOWED_PENDING_INTENT, even so the creator would have granted BAL permissions on its own. With this change we consistently use the creator's status over the sender's. Test: atest ActivityStarterTests Bug: 306059525 Change-Id: I5fb586e7d9c9246657f51daad9257052ddb01328
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java166
2 files changed, 123 insertions, 49 deletions
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 055aa5bc9153..fc3a33883de6 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -648,8 +648,7 @@ public class BackgroundActivityStartController {
Slog.d(TAG, "Activity start allowed by caller. "
+ state.dump());
}
- // return the realCaller result for backwards compatibility
- return allowBasedOnRealCaller(state);
+ return allowBasedOnCaller(state);
}
if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) {
Slog.wtf(TAG,
@@ -658,8 +657,7 @@ public class BackgroundActivityStartController {
+ " AND the PI sender upgrades target_sdk to 34+! "
+ state.dump());
showBalRiskToast();
- // return the realCaller result for backwards compatibility
- return allowBasedOnRealCaller(state);
+ return allowBasedOnCaller(state);
}
Slog.wtf(TAG,
"Without Android 15 BAL hardening this activity start would be allowed"
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index ff55e95dcba9..c82f7513e347 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -88,6 +88,7 @@ import static org.mockito.ArgumentMatchers.notNull;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges;
+import android.app.ComponentOptions.BackgroundActivityStartMode;
import android.app.IApplicationThread;
import android.app.PictureInPictureParams;
import android.content.ComponentName;
@@ -914,31 +915,78 @@ public class ActivityStarterTests extends WindowTestsBase {
.mockStatic(FrameworkStatsLog.class)
.strictness(Strictness.LENIENT)
.startMocking();
- doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
- eq(START_ACTIVITIES_FROM_BACKGROUND),
- anyInt(), anyInt()));
- runAndVerifyBackgroundActivityStartsSubtest(
- "allowed_notAborted", false,
- UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
- UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
- false, true, false, false, false, false, false, false);
- verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
- "", // activity name
- BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
- UNIMPORTANT_UID,
- UNIMPORTANT_UID2,
- BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
- true, // opt in
- false, // but no explicit opt in
- BackgroundActivityStartController.BAL_BLOCK,
- true, // opt in
- false // but no explicit opt in
+ try {
+ doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
+ eq(START_ACTIVITIES_FROM_BACKGROUND),
+ anyInt(), anyInt()));
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "allowed_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
+ UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
+ false, true, false, false, false, false, false, false);
+ verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
+ "", // activity name
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ UNIMPORTANT_UID,
+ UNIMPORTANT_UID2,
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ true, // opt in
+ false, // but no explicit opt in
+ BackgroundActivityStartController.BAL_BLOCK,
+ true, // opt in
+ false // but no explicit opt in
));
- mockingSession.finishMocking();
+ } finally {
+ mockingSession.finishMocking();
+ }
}
/**
- * This test ensures proper logging for BAL_ALLOW_PENDING_INTENT.
+ * This test ensures proper logging for BAL_ALLOW_PENDING_INTENT, when the PendingIntent sender
+ * is the only reason BAL is allowed.
+ */
+ @Test
+ public void testBackgroundActivityStartsAllowed_loggingOnlyPendingIntentAllowed() {
+ doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
+ MockitoSession mockingSession = mockitoSession()
+ .mockStatic(ActivityTaskManagerService.class)
+ .mockStatic(FrameworkStatsLog.class)
+ .mockStatic(PendingIntentRecord.class)
+ .strictness(Strictness.LENIENT)
+ .startMocking();
+ try {
+ doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
+ eq(START_ACTIVITIES_FROM_BACKGROUND),
+ anyInt(), anyInt()));
+ doReturn(BackgroundStartPrivileges.allowBackgroundActivityStarts(null)).when(
+ () -> PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
+ anyObject(), anyInt(), anyObject()));
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "allowed_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
+ Process.SYSTEM_UID, true, PROCESS_STATE_BOUND_TOP,
+ false, true, false, false, false, false, false, false,
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED);
+ verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
+ DEFAULT_COMPONENT_PACKAGE_NAME + "/" + DEFAULT_COMPONENT_PACKAGE_NAME,
+ BackgroundActivityStartController.BAL_ALLOW_PENDING_INTENT,
+ UNIMPORTANT_UID,
+ Process.SYSTEM_UID,
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ false, // opt in
+ true, // explicit opt out
+ BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW,
+ true, // opt in
+ false // but no explicit opt in
+ ));
+ } finally {
+ mockingSession.finishMocking();
+ }
+ }
+
+ /**
+ * This test ensures proper logging for BAL_ALLOW_PENDING_INTENT, when the PendingIntent sender
+ * is not the primary reason to allow BAL (but the creator).
*/
@Test
public void testBackgroundActivityStartsAllowed_loggingPendingIntentAllowed() {
@@ -949,30 +997,34 @@ public class ActivityStarterTests extends WindowTestsBase {
.mockStatic(PendingIntentRecord.class)
.strictness(Strictness.LENIENT)
.startMocking();
- doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
- eq(START_ACTIVITIES_FROM_BACKGROUND),
- anyInt(), anyInt()));
- doReturn(BackgroundStartPrivileges.allowBackgroundActivityStarts(null)).when(
- () -> PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
- anyObject(), anyInt(), anyObject()));
- runAndVerifyBackgroundActivityStartsSubtest(
- "allowed_notAborted", false,
- UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
- Process.SYSTEM_UID, true, PROCESS_STATE_BOUND_TOP,
- false, true, false, false, false, false, false, false);
- verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
- DEFAULT_COMPONENT_PACKAGE_NAME + "/" + DEFAULT_COMPONENT_PACKAGE_NAME,
- BackgroundActivityStartController.BAL_ALLOW_PENDING_INTENT,
- UNIMPORTANT_UID,
- Process.SYSTEM_UID,
- BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
- true, // opt in
- false, // but no explicit opt in
- BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW,
- true, // opt in
- false // but no explicit opt in
+ try {
+ doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
+ eq(START_ACTIVITIES_FROM_BACKGROUND),
+ anyInt(), anyInt()));
+ doReturn(BackgroundStartPrivileges.allowBackgroundActivityStarts(null)).when(
+ () -> PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
+ anyObject(), anyInt(), anyObject()));
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "allowed_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
+ Process.SYSTEM_UID, true, PROCESS_STATE_BOUND_TOP,
+ false, true, false, false, false, false, false, false,
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
+ "",
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ UNIMPORTANT_UID,
+ Process.SYSTEM_UID,
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ true, // opt in
+ true, // explicit opt in
+ BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW,
+ true, // opt in
+ false // but no explicit opt in
));
- mockingSession.finishMocking();
+ } finally {
+ mockingSession.finishMocking();
+ }
}
private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
@@ -985,6 +1037,27 @@ public class ActivityStarterTests extends WindowTestsBase {
boolean isCallingUidAffiliatedProfileOwner,
boolean isPinnedSingleInstance,
boolean hasSystemExemptAppOp) {
+ runAndVerifyBackgroundActivityStartsSubtest(name, shouldHaveAborted, callingUid,
+ callingUidHasVisibleWindow, callingUidProcState, realCallingUid,
+ realCallingUidHasVisibleWindow, realCallingUidProcState, hasForegroundActivities,
+ callerIsRecents, callerIsTempAllowed,
+ callerIsInstrumentingWithBackgroundActivityStartPrivileges,
+ isCallingUidDeviceOwner, isCallingUidAffiliatedProfileOwner, isPinnedSingleInstance,
+ hasSystemExemptAppOp,
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
+ }
+
+ private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
+ int callingUid, boolean callingUidHasVisibleWindow, int callingUidProcState,
+ int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState,
+ boolean hasForegroundActivities, boolean callerIsRecents,
+ boolean callerIsTempAllowed,
+ boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
+ boolean isCallingUidDeviceOwner,
+ boolean isCallingUidAffiliatedProfileOwner,
+ boolean isPinnedSingleInstance,
+ boolean hasSystemExemptAppOp,
+ @BackgroundActivityStartMode int pendingIntentCreatorBackgroundActivityStartMode) {
// window visibility
doReturn(callingUidHasVisibleWindow).when(mAtm).hasActiveVisibleWindow(callingUid);
doReturn(realCallingUidHasVisibleWindow).when(mAtm).hasActiveVisibleWindow(realCallingUid);
@@ -1036,7 +1109,10 @@ public class ActivityStarterTests extends WindowTestsBase {
launchMode = LAUNCH_SINGLE_INSTANCE;
}
- final ActivityOptions options = spy(ActivityOptions.makeBasic());
+ ActivityOptions rawOptions = ActivityOptions.makeBasic()
+ .setPendingIntentCreatorBackgroundActivityStartMode(
+ pendingIntentCreatorBackgroundActivityStartMode);
+ final ActivityOptions options = spy(rawOptions);
ActivityRecord[] outActivity = new ActivityRecord[1];
ActivityStarter starter = prepareStarter(
FLAG_ACTIVITY_NEW_TASK, true, launchMode)