summaryrefslogtreecommitdiff
path: root/core/java/android/widget/TextView.java
diff options
context:
space:
mode:
authorFelka Chang <felkachang@google.com>2019-04-02 16:24:49 +0800
committerFelka Chang <felkachang@google.com>2019-05-21 14:16:59 +0800
commit33f56060d57a0aca3693caedbc37b5dc94a11ef3 (patch)
tree6c90b32c66944c43b6df32c1efe8cc23bb8f0da9 /core/java/android/widget/TextView.java
parenta35495ffa371949b9176a4500e7fccc7cd0abb23 (diff)
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
Diffstat (limited to 'core/java/android/widget/TextView.java')
-rw-r--r--core/java/android/widget/TextView.java31
1 files changed, 18 insertions, 13 deletions
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> T getServiceManagerForUser(String packageName, Class<T> 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) {