diff options
| author | 2023-12-22 03:48:58 +0000 | |
|---|---|---|
| committer | 2024-01-04 01:47:27 +0000 | |
| commit | 2e76468c158ddecbf22ab33c8f525b0e79382ca1 (patch) | |
| tree | 3cb6f080d09175255c19832cf4b0108af32403a9 | |
| parent | 62acf9ae3a06460c41a2856922ce1076ed11d52f (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.java | 6 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java | 166 |
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) |