summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Gavin Corkery <gavincorkery@google.com> 2022-03-03 16:19:48 +0000
committer Gavin Corkery <gavincorkery@google.com> 2022-03-15 18:40:22 +0000
commit5c111ff67fdacba0fd6d23f6842044ca529a49ed (patch)
treec157afb9fb74cdb8ec6b9e247fbea60bac7dcba6
parentb78bf4e4d7b9d19c8872c76e95a001adcecc315d (diff)
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
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java11
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java15
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java11
-rw-r--r--services/tests/wmtests/Android.bp1
4 files changed, 38 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0735648c1069..489aaec13bf0 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 7d2dfa071597..e85eb6db94a2 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 b5312c4de437..ad164e22c465 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 57bbe40c5b06..079d765868fd 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: [