From 34ffba62b351abf4710a9e64ed345658d2069c37 Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Thu, 2 Mar 2017 15:56:43 -0800 Subject: [PATCH] Limit instant app access to clipboard Instant apps can access the clipboard (both read and write) in order for copy/paste UI to work correctly. In order to limit the exposure of user data Instant Apps can only access the clipboard while running in the foreground. Longer term it would be nice to gate Instant Apps clipboard access around user interaction to prevent shenanigains, but this is a good start. Test: Manually verified that ClipboardManager.getPrimaryClip returns null when the instant app transitions out of the foreground Bug: 34231507 Change-Id: I7ea83e503d249c61e9df2d8bd83028e24705be11 --- .../server/clipboard/ClipboardService.java | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 94417b531c712..8abde78c2e661 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -255,8 +255,8 @@ public class ClipboardService extends SystemService { clip.getItemAt(0).getText().toString()); } final int callingUid = Binder.getCallingUid(); - if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, callingUid, - callingPackage) != AppOpsManager.MODE_ALLOWED) { + if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage, + callingUid)) { return; } checkDataOwnerLocked(clip, callingUid); @@ -304,8 +304,8 @@ public class ClipboardService extends SystemService { @Override public ClipData getPrimaryClip(String pkg) { synchronized (this) { - if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), - pkg) != AppOpsManager.MODE_ALLOWED) { + if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, pkg, + Binder.getCallingUid())) { return null; } addActiveOwnerLocked(Binder.getCallingUid(), pkg); @@ -316,8 +316,8 @@ public class ClipboardService extends SystemService { @Override public ClipDescription getPrimaryClipDescription(String callingPackage) { synchronized (this) { - if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { + if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage, + Binder.getCallingUid())) { return null; } PerUserClipboard clipboard = getClipboard(); @@ -328,8 +328,8 @@ public class ClipboardService extends SystemService { @Override public boolean hasPrimaryClip(String callingPackage) { synchronized (this) { - if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { + if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage, + Binder.getCallingUid())) { return false; } return getClipboard().primaryClip != null; @@ -355,8 +355,8 @@ public class ClipboardService extends SystemService { @Override public boolean hasClipboardText(String callingPackage) { synchronized (this) { - if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), - callingPackage) != AppOpsManager.MODE_ALLOWED) { + if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage, + Binder.getCallingUid())) { return false; } PerUserClipboard clipboard = getClipboard(); @@ -417,8 +417,9 @@ public class ClipboardService extends SystemService { try { ListenerInfo li = (ListenerInfo) clipboard.primaryClipListeners.getBroadcastCookie(i); - if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid, - li.mPackageName) == AppOpsManager.MODE_ALLOWED) { + + if (clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, li.mPackageName, + li.mUid)) { clipboard.primaryClipListeners.getBroadcastItem(i) .dispatchPrimaryClipChanged(); } @@ -551,4 +552,24 @@ public class ClipboardService extends SystemService { revokeItemLocked(clipboard.primaryClip.getItemAt(i)); } } + + private boolean clipboardAccessAllowed(int op, String callingPackage, int callingUid) { + // Check the AppOp. + if (mAppOps.checkOp(op, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) { + return false; + } + try { + // Installed apps can access the clipboard at any time. + if (!AppGlobals.getPackageManager().isInstantApp(callingPackage, + UserHandle.getUserId(callingUid))) { + return true; + } + // Instant apps can only access the clipboard if they are in the foreground. + return mAm.isAppForeground(callingUid); + } catch (RemoteException e) { + Slog.e("clipboard", "Failed to get Instant App status for package " + callingPackage, + e); + return false; + } + } }