Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34ffba62 authored by Chad Brubaker's avatar Chad Brubaker
Browse files

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
parent 748bf772
Loading
Loading
Loading
Loading
+33 −12
Original line number Original line Diff line number Diff line
@@ -255,8 +255,8 @@ public class ClipboardService extends SystemService {
                        clip.getItemAt(0).getText().toString());
                        clip.getItemAt(0).getText().toString());
                }
                }
                final int callingUid = Binder.getCallingUid();
                final int callingUid = Binder.getCallingUid();
                if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, callingUid,
                if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage,
                        callingPackage) != AppOpsManager.MODE_ALLOWED) {
                            callingUid)) {
                    return;
                    return;
                }
                }
                checkDataOwnerLocked(clip, callingUid);
                checkDataOwnerLocked(clip, callingUid);
@@ -304,8 +304,8 @@ public class ClipboardService extends SystemService {
        @Override
        @Override
        public ClipData getPrimaryClip(String pkg) {
        public ClipData getPrimaryClip(String pkg) {
            synchronized (this) {
            synchronized (this) {
                if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, pkg,
                        pkg) != AppOpsManager.MODE_ALLOWED) {
                            Binder.getCallingUid())) {
                    return null;
                    return null;
                }
                }
                addActiveOwnerLocked(Binder.getCallingUid(), pkg);
                addActiveOwnerLocked(Binder.getCallingUid(), pkg);
@@ -316,8 +316,8 @@ public class ClipboardService extends SystemService {
        @Override
        @Override
        public ClipDescription getPrimaryClipDescription(String callingPackage) {
        public ClipDescription getPrimaryClipDescription(String callingPackage) {
            synchronized (this) {
            synchronized (this) {
                if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                        callingPackage) != AppOpsManager.MODE_ALLOWED) {
                            Binder.getCallingUid())) {
                    return null;
                    return null;
                }
                }
                PerUserClipboard clipboard = getClipboard();
                PerUserClipboard clipboard = getClipboard();
@@ -328,8 +328,8 @@ public class ClipboardService extends SystemService {
        @Override
        @Override
        public boolean hasPrimaryClip(String callingPackage) {
        public boolean hasPrimaryClip(String callingPackage) {
            synchronized (this) {
            synchronized (this) {
                if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                        callingPackage) != AppOpsManager.MODE_ALLOWED) {
                            Binder.getCallingUid())) {
                    return false;
                    return false;
                }
                }
                return getClipboard().primaryClip != null;
                return getClipboard().primaryClip != null;
@@ -355,8 +355,8 @@ public class ClipboardService extends SystemService {
        @Override
        @Override
        public boolean hasClipboardText(String callingPackage) {
        public boolean hasClipboardText(String callingPackage) {
            synchronized (this) {
            synchronized (this) {
                if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                        callingPackage) != AppOpsManager.MODE_ALLOWED) {
                            Binder.getCallingUid())) {
                    return false;
                    return false;
                }
                }
                PerUserClipboard clipboard = getClipboard();
                PerUserClipboard clipboard = getClipboard();
@@ -417,8 +417,9 @@ public class ClipboardService extends SystemService {
                try {
                try {
                    ListenerInfo li = (ListenerInfo)
                    ListenerInfo li = (ListenerInfo)
                            clipboard.primaryClipListeners.getBroadcastCookie(i);
                            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)
                        clipboard.primaryClipListeners.getBroadcastItem(i)
                                .dispatchPrimaryClipChanged();
                                .dispatchPrimaryClipChanged();
                    }
                    }
@@ -551,4 +552,24 @@ public class ClipboardService extends SystemService {
            revokeItemLocked(clipboard.primaryClip.getItemAt(i));
            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;
        }
    }
}
}