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

Commit a98b760f authored by Chad Brubaker's avatar Chad Brubaker
Browse files

Move non-access methods to checkOp

ClipboardService previously used noteOp for all clipboard operations,
but this leads to the data being polluted by non-access methods like
getClipDescription and hasPrimaryClip. Move those methods to checkOps
instead.

This also moves the app op check to the end to avoid logging in
scenarios we would have rejected access anyways.

Fixes: 160791050
Test: atest ClipboardManagerTest
Change-Id: Ibb9299f918fcb5ef406f35405769099d179bdcd3
parent 5c25605d
Loading
Loading
Loading
Loading
+38 −18
Original line number Original line Diff line number Diff line
@@ -400,7 +400,7 @@ public class ClipboardService extends SystemService {
                final int intendingUid = getIntendingUid(callingPackage, userId);
                final int intendingUid = getIntendingUid(callingPackage, userId);
                final int intendingUserId = UserHandle.getUserId(intendingUid);
                final int intendingUserId = UserHandle.getUserId(intendingUid);
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                        intendingUid, intendingUserId)
                        intendingUid, intendingUserId, false)
                        || isDeviceLocked(intendingUserId)) {
                        || isDeviceLocked(intendingUserId)) {
                    return null;
                    return null;
                }
                }
@@ -416,7 +416,7 @@ public class ClipboardService extends SystemService {
                final int intendingUid = getIntendingUid(callingPackage, userId);
                final int intendingUid = getIntendingUid(callingPackage, userId);
                final int intendingUserId = UserHandle.getUserId(intendingUid);
                final int intendingUserId = UserHandle.getUserId(intendingUid);
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                        intendingUid, intendingUserId)
                        intendingUid, intendingUserId, false)
                        || isDeviceLocked(intendingUserId)) {
                        || isDeviceLocked(intendingUserId)) {
                    return false;
                    return false;
                }
                }
@@ -450,7 +450,7 @@ public class ClipboardService extends SystemService {
                final int intendingUid = getIntendingUid(callingPackage, userId);
                final int intendingUid = getIntendingUid(callingPackage, userId);
                final int intendingUserId = UserHandle.getUserId(intendingUid);
                final int intendingUserId = UserHandle.getUserId(intendingUid);
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
                        intendingUid, intendingUserId)
                        intendingUid, intendingUserId, false)
                        || isDeviceLocked(intendingUserId)) {
                        || isDeviceLocked(intendingUserId)) {
                    return false;
                    return false;
                }
                }
@@ -740,14 +740,21 @@ public class ClipboardService extends SystemService {


    private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
    private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
            @UserIdInt int userId) {
            @UserIdInt int userId) {
        // Check the AppOp.
        return clipboardAccessAllowed(op, callingPackage, uid, userId, true);
        if (mAppOps.noteOp(op, uid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
            return false;
    }
    }

    private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
            @UserIdInt int userId, boolean shouldNoteOp) {

        boolean allowed = false;

        // First, verify package ownership to ensure use below is safe.
        mAppOps.checkPackage(uid, callingPackage);

        // Shell can access the clipboard for testing purposes.
        // Shell can access the clipboard for testing purposes.
        if (mPm.checkPermission(android.Manifest.permission.READ_CLIPBOARD_IN_BACKGROUND,
        if (mPm.checkPermission(android.Manifest.permission.READ_CLIPBOARD_IN_BACKGROUND,
                    callingPackage) == PackageManager.PERMISSION_GRANTED) {
                    callingPackage) == PackageManager.PERMISSION_GRANTED) {
            return true;
            allowed = true;
        }
        }
        // The default IME is always allowed to access the clipboard.
        // The default IME is always allowed to access the clipboard.
        String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
        String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
@@ -755,7 +762,7 @@ public class ClipboardService extends SystemService {
        if (!TextUtils.isEmpty(defaultIme)) {
        if (!TextUtils.isEmpty(defaultIme)) {
            final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName();
            final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName();
            if (imePkg.equals(callingPackage)) {
            if (imePkg.equals(callingPackage)) {
                return true;
                allowed = true;
            }
            }
        }
        }


@@ -766,8 +773,10 @@ public class ClipboardService extends SystemService {
                // at the same time. e.x. SystemUI. It needs to check the window focus of
                // at the same time. e.x. SystemUI. It needs to check the window focus of
                // Binder.getCallingUid(). Without checking, the user X can't copy any thing from
                // Binder.getCallingUid(). Without checking, the user X can't copy any thing from
                // INTERNAL_SYSTEM_WINDOW to the other applications.
                // INTERNAL_SYSTEM_WINDOW to the other applications.
                boolean allowed = mWm.isUidFocused(uid)
                if (!allowed) {
                    allowed = mWm.isUidFocused(uid)
                            || isInternalSysWindowAppWithWindowFocus(callingPackage);
                            || isInternalSysWindowAppWithWindowFocus(callingPackage);
                }
                if (!allowed && mContentCaptureInternal != null) {
                if (!allowed && mContentCaptureInternal != null) {
                    // ...or the Content Capture Service
                    // ...or the Content Capture Service
                    // The uid parameter of mContentCaptureInternal.isContentCaptureServiceForUser
                    // The uid parameter of mContentCaptureInternal.isContentCaptureServiceForUser
@@ -786,17 +795,28 @@ public class ClipboardService extends SystemService {
                    // userId must pass intending userId. i.e. user#10.
                    // userId must pass intending userId. i.e. user#10.
                    allowed = mAutofillInternal.isAugmentedAutofillServiceForUser(uid, userId);
                    allowed = mAutofillInternal.isAugmentedAutofillServiceForUser(uid, userId);
                }
                }
                if (!allowed) {
                break;
                    Slog.e(TAG, "Denying clipboard access to " + callingPackage
                            + ", application is not in focus neither is a system service for "
                            + "user " + userId);
                }
                return allowed;
            case AppOpsManager.OP_WRITE_CLIPBOARD:
            case AppOpsManager.OP_WRITE_CLIPBOARD:
                // Writing is allowed without focus.
                // Writing is allowed without focus.
                return true;
                allowed = true;
                break;
            default:
            default:
                throw new IllegalArgumentException("Unknown clipboard appop " + op);
                throw new IllegalArgumentException("Unknown clipboard appop " + op);
        }
        }
        if (!allowed) {
            Slog.e(TAG, "Denying clipboard access to " + callingPackage
                    + ", application is not in focus nor is it a system service for "
                    + "user " + userId);
            return false;
        }
        // Finally, check the app op.
        int appOpsResult;
        if (shouldNoteOp) {
            appOpsResult = mAppOps.noteOp(op, uid, callingPackage);
        } else {
            appOpsResult = mAppOps.checkOp(op, uid, callingPackage);
        }

        return appOpsResult == AppOpsManager.MODE_ALLOWED;
    }
    }
}
}