From 6fcbfc3962d8457cf8ed9dc36962b2ff4bc78724 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Tue, 26 Apr 2022 15:51:30 +0800 Subject: [PATCH] Fix crash for cross-process embedding 1. For TaskFragment#isAllowedToBeEmbeddedInTrustedMode, it should return false if any child activity is not in trusted mode. 2. We don't need to check requested bounds if it is empty. Bug: 197364677 Test: atest WmTests:TaskFragmentTest Change-Id: Ic9eab24f6e8530c03910e4ffaeeb6d3b69591ec7 --- .../com/android/server/wm/TaskFragment.java | 5 ++-- .../server/wm/WindowOrganizerController.java | 4 ++- .../android/server/wm/TaskFragmentTest.java | 25 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 1beb32cfdd521..4cb4e91755340 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -591,8 +591,9 @@ class TaskFragment extends WindowContainer { * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord) */ boolean isAllowedToBeEmbeddedInTrustedMode() { - final Predicate callback = this::isAllowedToEmbedActivityInTrustedMode; - return forAllActivities(callback); + // Traverse all activities to see if any of them are not in the trusted mode. + final Predicate callback = r -> !isAllowedToEmbedActivityInTrustedMode(r); + return !forAllActivities(callback); } /** diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 7de8ed5977620..137a3ac81b9b5 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -1438,7 +1438,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } final WindowConfiguration requestedWindowConfig = requestedConfig.windowConfiguration; final WindowConfiguration parentWindowConfig = parentConfig.windowConfiguration; - if (!parentWindowConfig.getBounds().contains(requestedWindowConfig.getBounds())) { + if (!requestedWindowConfig.getBounds().isEmpty() + && !parentWindowConfig.getBounds().contains(requestedWindowConfig.getBounds())) { String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " trying to apply bounds outside of parent for non-trusted host," @@ -1447,6 +1448,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub throw new SecurityException(msg); } if (requestedWindowConfig.getAppBounds() != null + && !requestedWindowConfig.getAppBounds().isEmpty() && parentWindowConfig.getAppBounds() != null && !parentWindowConfig.getAppBounds().contains( requestedWindowConfig.getAppBounds())) { diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java index 3c14777cd7d16..b2043c38d00ad 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java @@ -403,4 +403,29 @@ public class TaskFragmentTest extends WindowTestsBase { assertFalse(activity0.hasOverlayOverUntrustedModeEmbedded()); assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded()); } + + @Test + public void testIsAllowedToBeEmbeddedInTrustedMode() { + final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm) + .setCreateParentTask() + .createActivityCount(2) + .build(); + final ActivityRecord activity0 = taskFragment.getBottomMostActivity(); + final ActivityRecord activity1 = taskFragment.getTopMostActivity(); + + // Allowed if all children activities are allowed. + doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0); + doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1); + + assertTrue(taskFragment.isAllowedToBeEmbeddedInTrustedMode()); + + // Disallowed if any child activity is not allowed. + doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0); + + assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode()); + + doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1); + + assertFalse(taskFragment.isAllowedToBeEmbeddedInTrustedMode()); + } }