summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrii Kulian <akulian@google.com>2017-06-28 09:42:48 -0700
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-06-29 04:38:14 +0000
commited115cd696309ae9d164c603fcf7417e9f6c079f (patch)
tree61d96f42382ea14297f3033538e20601ca870b0b
parent1382fd7edb10a88915a59bedbc8897bed80e32d2 (diff)
downloadbase-ed115cd696309ae9d164c603fcf7417e9f6c079f.tar.gz
Restrict launching activities on virtual displays
If an app creates a Surface and a virtual display backed by that Surface, it can then launch activities and hijack their content. This CL restrict activities that can be launched to virtual displays created by apps only to those who set "allowEmbedded" attribute. If a virtual display was created by system, apps won't get access to the surface, so we're not limiting in this case. Bug: 63094482 Test: android.server.cts.ActivityManagerDisplayTests Test: #testLaunchNotEmbeddedOnVirtualDisplay Change-Id: Ied216bdf33df4b5a6cc8cac0e006a4883a36f94f (cherry picked from commit 1cba31c3dc307a8629d32434bd5846a0097c240a)
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java36
1 files changed, 25 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index fe0e07efe9bc..50233f360a33 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -38,11 +38,13 @@ import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCRE
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
+import static android.view.Display.TYPE_VIRTUAL;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -1654,7 +1656,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// owner.
final int launchDisplayId = options.getLaunchDisplayId();
if (launchDisplayId != INVALID_DISPLAY
- && !isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, launchDisplayId)) {
+ && !isCallerAllowedToLaunchOnDisplay(callingPid, callingUid, launchDisplayId,
+ aInfo)) {
final String msg = "Permission Denial: starting " + intent.toString()
+ " from " + callerApp + " (pid=" + callingPid
+ ", uid=" + callingUid + ") with launchDisplayId="
@@ -1668,7 +1671,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
}
/** Check if caller is allowed to launch activities on specified display. */
- boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId) {
+ boolean isCallerAllowedToLaunchOnDisplay(int callingPid, int callingUid, int launchDisplayId,
+ ActivityInfo aInfo) {
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check: displayId=" + launchDisplayId
+ " callingPid=" + callingPid + " callingUid=" + callingUid);
@@ -1678,6 +1682,25 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
return false;
}
+ // Check if the caller can manage activity stacks.
+ final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
+ callingUid);
+ if (startAnyPerm == PERMISSION_GRANTED) {
+ if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+ + " allow launch any on display");
+ return true;
+ }
+
+ if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL
+ && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID
+ && (aInfo.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
+ // Limit launching on virtual displays, because their contents can be read from Surface
+ // by apps that created them.
+ if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+ + " disallow launch on virtual display for not-embedded activity");
+ return false;
+ }
+
if (!activityDisplay.isPrivate()) {
// Anyone can launch on a public display.
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1699,15 +1722,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
return true;
}
- // Check if the caller can manage activity stacks.
- final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
- callingUid);
- if (startAnyPerm == PERMISSION_GRANTED) {
- if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
- + " allow launch any on display");
- return true;
- }
-
Slog.w(TAG, "Launch on display check: denied");
return false;
}