From 5c111ff67fdacba0fd6d23f6842044ca529a49ed Mon Sep 17 00:00:00 2001 From: Gavin Corkery Date: Thu, 3 Mar 2022 16:19:48 +0000 Subject: [PATCH] Add checks to allow SDK sandbox uids to broadcast certain intents Integrates ActivityManager with new in-process APIs defined by SdkSandboxManagerLocal, which check if a sandbox uid is allowed to broadcast a given intent or start an activity with a given intent. If the intent is not allowed, a SecurityException is thrown. This change also adds several checks to the intent broadcast and activity starting flow to accommodate the sdk sandbox process. The goal of these checks is to ensure that something visible to the user is running inside the SDK sandbox process when a broadcast is sent or an activity is started. Bug: 209599396 Test: Manual tests. Send ACTION_VIEW broadcast from sdk sandbox testing apps and note that activity starts. Try to send other broadcast and note failure. Change-Id: Ia60e4a062efeef6f281c8bc28343c64f7f3936ab --- .../android/server/am/ActivityManagerService.java | 11 +++++++++++ .../com/android/server/wm/ActivityStarter.java | 15 +++++++++++++++ .../server/wm/ActivityTaskManagerService.java | 11 +++++++++++ services/tests/wmtests/Android.bp | 1 + 4 files changed, 38 insertions(+) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0735648c1069a..489aaec13bf08 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -406,6 +406,7 @@ import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.pm.pkg.SELinuxUtil; import com.android.server.pm.pkg.parsing.ParsingPackageUtils; import com.android.server.pm.snapshot.PackageDataSnapshot; +import com.android.server.sdksandbox.SdkSandboxManagerLocal; import com.android.server.uri.GrantUri; import com.android.server.uri.NeededUriGrants; import com.android.server.uri.UriGrantsManagerInternal; @@ -13536,6 +13537,16 @@ public class ActivityManagerService extends IActivityManager.Stub intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); } + if (Process.isSdkSandboxUid(realCallingUid)) { + SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager( + SdkSandboxManagerLocal.class); + if (sdkSandboxManagerLocal == null) { + throw new IllegalStateException("SdkSandboxManagerLocal not found when sending" + + " a broadcast from an SDK sandbox uid."); + } + sdkSandboxManagerLocal.enforceAllowedToSendBroadcast(intent); + } + switch (action) { case Intent.ACTION_MEDIA_SCANNER_SCAN_FILE: UserManagerInternal umInternal = LocalServices.getService( diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 7d2dfa0715979..e85eb6db94a2c 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1333,6 +1333,21 @@ class ActivityStarter { : (realCallingAppId == Process.SYSTEM_UID) || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; + // In the case of an SDK sandbox calling uid, check if the corresponding app uid has a + // visible window. + if (Process.isSdkSandboxUid(realCallingUid)) { + int realCallingSdkSandboxUidToAppUid = Process.getAppUidForSdkSandboxUid( + UserHandle.getAppId(realCallingUid)); + + if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) { + if (DEBUG_ACTIVITY_STARTS) { + Slog.d(TAG, "Activity start allowed: uid in SDK sandbox (" + + realCallingUid + ") has visible (non-toast) window."); + } + return false; + } + } + // Legacy behavior allows to use caller foreground state to bypass BAL restriction. final boolean balAllowedByPiSender = PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index b5312c4de4373..ad164e22c4651 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -244,6 +244,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.function.pooled.PooledLambda; +import com.android.server.LocalManagerRegistry; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemServiceManager; @@ -260,6 +261,7 @@ import com.android.server.am.UserState; import com.android.server.firewall.IntentFirewall; import com.android.server.pm.UserManagerService; import com.android.server.policy.PermissionPolicyInternal; +import com.android.server.sdksandbox.SdkSandboxManagerLocal; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.uri.UriGrantsManagerInternal; @@ -1236,6 +1238,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { assertPackageMatchesCallingUid(callingPackage); enforceNotIsolatedCaller("startActivityAsUser"); + if (Process.isSdkSandboxUid(Binder.getCallingUid())) { + SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager( + SdkSandboxManagerLocal.class); + if (sdkSandboxManagerLocal == null) { + throw new IllegalStateException("SdkSandboxManagerLocal not found when starting" + + " an activity from an SDK sandbox uid."); + } + sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent); + } userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp index 57bbe40c5b065..079d765868fd4 100644 --- a/services/tests/wmtests/Android.bp +++ b/services/tests/wmtests/Android.bp @@ -58,6 +58,7 @@ android_test { "hamcrest-library", "platform-compat-test-rules", "CtsSurfaceValidatorLib", + "service-sdksandbox.impl", ], libs: [