From 33f56060d57a0aca3693caedbc37b5dc94a11ef3 Mon Sep 17 00:00:00 2001 From: Felka Chang Date: Tue, 2 Apr 2019 16:24:49 +0800 Subject: Fix sysui's security issue of cross-user copy/paste Background: The applications with the granted INTERNAL_SYSTEM_WINDOW and INTERACT_ACROSS_USERS_FULL means that it could show the same window for all of users. i.e. to use user 0 presents all of UI things to all of users. INTERNAL_SYSTEM_WINDOW usually comes with INTERACT_ACROSS_USERS_FULL because it will serve all of users to know the information that comes from framework and system server. Solution: Because SystemUI never restarts after the user changing, ClipboardService can't tell if the callingUid has the the same userId with the current user or not. The solution is to use the permission check. Especially, INTERACT_ACROSS_USERS_FULL and INTERNAL_SYSTEM_WINDOW. To check INTERACT_ACROSS_USERS_FULL by using ActivityManagerInternal.handleIncomingUser. Caution: The application with INTERNAL_SYSTEM_WINDOW usually use user 0 to show the window. But, the current user is user 10, WindowManager know the focus windows is belong to user 0 rather user 10. That's why user 10 can't copy the the text from systemui directly reply to the other applications. Readability: ClipboardService use callingUid everywhere but actaully it is not appropriated to fix this kind of bug. This patch refactor the naming to produce two name. i.e. intendingUid and intentdingUserId that are validated by ActivityManagerInternal.handleIncomingUser. Test: manual test Test: atest android.widget.cts.TextViewTest Test: atest CtsTextTestCases Test: atest CtsContentTestCases Bug: 123232892 Bug: 117768051 Change-Id: Ie3daecd1e8fc2f7fdf37baeb5979da9f2e0b3937 --- core/java/android/widget/TextView.java | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'core/java/android/widget/TextView.java') diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 17c56c3f216a..a9e183ad5bf2 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -11244,13 +11244,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Nullable final TextServicesManager getTextServicesManagerForUser() { + return getServiceManagerForUser("android", TextServicesManager.class); + } + + @Nullable + final ClipboardManager getClipboardManagerForUser() { + return getServiceManagerForUser(getContext().getPackageName(), ClipboardManager.class); + } + + @Nullable + final T getServiceManagerForUser(String packageName, Class managerClazz) { if (mTextOperationUser == null) { - return getContext().getSystemService(TextServicesManager.class); + return getContext().getSystemService(managerClazz); } try { - return getContext().createPackageContextAsUser( - "android", 0 /* flags */, mTextOperationUser) - .getSystemService(TextServicesManager.class); + Context context = getContext().createPackageContextAsUser( + packageName, 0 /* flags */, mTextOperationUser); + return context.getSystemService(managerClazz); } catch (PackageManager.NameNotFoundException e) { return null; } @@ -12540,8 +12550,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener && mEditor != null && mEditor.mKeyListener != null && getSelectionStart() >= 0 && getSelectionEnd() >= 0 - && ((ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE)) - .hasPrimaryClip()); + && getClipboardManagerForUser().hasPrimaryClip()); } boolean canPasteAsPlainText() { @@ -12549,9 +12558,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return false; } - final ClipData clipData = - ((ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE)) - .getPrimaryClip(); + final ClipData clipData = getClipboardManagerForUser().getPrimaryClip(); final ClipDescription description = clipData.getDescription(); final boolean isPlainType = description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN); final CharSequence text = clipData.getItemAt(0).getText(); @@ -12594,8 +12601,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * Paste clipboard content between min and max positions. */ private void paste(int min, int max, boolean withFormatting) { - ClipboardManager clipboard = - (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); + ClipboardManager clipboard = getClipboardManagerForUser(); ClipData clip = clipboard.getPrimaryClip(); if (clip != null) { boolean didFirst = false; @@ -12638,8 +12644,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @CheckResult private boolean setPrimaryClip(ClipData clip) { - ClipboardManager clipboard = - (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); + ClipboardManager clipboard = getClipboardManagerForUser(); try { clipboard.setPrimaryClip(clip); } catch (Throwable t) { -- cgit v1.2.3