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

Commit 73ca6039 authored by Surbhi Kadam's avatar Surbhi Kadam Committed by Markus S
Browse files

Sanitize window private flags based on caller permissions.

Introduces `sanitizePrivateFlags` to check if the calling application has the necessary permissions to set certain `LayoutParams.privateFlags`. Specifically, `PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY` and `PRIVATE_FLAG_TRUSTED_OVERLAY` require `INTERNAL_SYSTEM_WINDOW`, and `PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP` requires `MANAGE_ACTIVITY_TASKS`. These flags are removed if the caller lacks the required permissions during window relayout.

Bug: 406243581
Test: atest WindowManagerServiceTests
Flag: EXEMPT bug fix

(cherry picked from commit ec6a92be)
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:de831dc7ee8d95de5568cd981f82b92f1fc29f0a
Merged-In: I4fdf2152f06082e13690e7f5b628e0ca0acdff84
Change-Id: I4fdf2152f06082e13690e7f5b628e0ca0acdff84
parent 8b361cb2
Loading
Loading
Loading
Loading
+30 −1
Original line number Diff line number Diff line
@@ -1879,7 +1879,8 @@ public class WindowManagerService extends IWindowManager.Stub
        final boolean hasStatusBarServicePermission =
                mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE)
                        == PackageManager.PERMISSION_GRANTED;

        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        long origId = Binder.clearCallingIdentity();
        final int displayId;
        synchronized(mWindowMap) {
@@ -1906,6 +1907,8 @@ public class WindowManagerService extends IWindowManager.Stub
            int flagChanges = 0;
            if (attrs != null) {
                mPolicy.adjustWindowParamsLw(win, attrs, hasStatusBarServicePermission);
                attrs.privateFlags = sanitizePrivateFlags(attrs.privateFlags,
                        win.mAttrs.privateFlags, win.getName(), uid, pid);
                // if they don't have the permission, mask out the status bar bits
                if (seq == win.mSeq) {
                    int systemUiVisibility = attrs.systemUiVisibility
@@ -7644,4 +7647,30 @@ public class WindowManagerService extends IWindowManager.Stub
            }
        }
    }

    private boolean hasFlags(int flags, int mask) {
        return (flags & mask) != 0;
    }

    private boolean hasPermission(String permission, int callingPid, int callingUid) {
        return mContext.checkPermission(permission, callingPid, callingUid)
                == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * Ensure the caller has the right permissions to be able to set the requested private flags.
     */
    private int sanitizePrivateFlags(int newPrivateFlags, int oldPrivateFlags, String windowName,
            int callingUid, int callingPid) {
        final int addedPrivateFlags = ~oldPrivateFlags & newPrivateFlags;
        int sanitizedFlags = newPrivateFlags;
        if (hasFlags(addedPrivateFlags, PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY)
                && !hasPermission(android.Manifest.permission.INTERNAL_SYSTEM_WINDOW,
                    callingUid, callingPid)) {
            Slog.w(TAG, "Removing PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY from '" + windowName
                    + "' because it doesn't have INTERNAL_SYSTEM_WINDOW permission");
            sanitizedFlags &= ~(PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY);
        }
        return sanitizedFlags;
    }
}