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

Commit 67a379b7 authored by Chilun's avatar Chilun Committed by Chilun Huang
Browse files

Don't allow enabling system decorations for untrusted virtual displays (1/2)

We should only allow enabling system decorations for callers with the
right permission.

Bug: 130284250
Test: atest MultiDisplaySystemDecorationTests
Test: atest MultiDisplayPolicyTests
Test: atest ActivityManagerGetConfigTests#testDeviceConfigWithSecondaryDisplay
Test: atest MultiDisplayActivityLaunchTests#testLaunchExternalDisplayActivityWhilePrimaryOff
Change-Id: I008d44bdf1378a675a3197e1467521dcf7b275c5
parent 8bfe7fd3
Loading
Loading
Loading
Loading
+29 −8
Original line number Original line Diff line number Diff line
@@ -16,12 +16,15 @@


package com.android.server.display;
package com.android.server.display;


import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT;
import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
import static android.hardware.display.DisplayManager
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
        .VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
@@ -1979,6 +1982,18 @@ public final class DisplayManagerService extends SystemService {
                }
                }
            }
            }


            // Sometimes users can have sensitive information in system decoration windows. An app
            // could create a virtual display with system decorations support and read the user info
            // from the surface.
            // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
            // to virtual displays that are owned by the system.
            if (callingUid != Process.SYSTEM_UID
                    && (flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
                if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
                    throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
                }
            }

            final long token = Binder.clearCallingIdentity();
            final long token = Binder.clearCallingIdentity();
            try {
            try {
                return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
                return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
@@ -2279,9 +2294,7 @@ public final class DisplayManagerService extends SystemService {
                    Slog.e(TAG, "Unable to query projection service for permissions", e);
                    Slog.e(TAG, "Unable to query projection service for permissions", e);
                }
                }
            }
            }
            if (mContext.checkCallingPermission(
            if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) {
                    android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
                    == PackageManager.PERMISSION_GRANTED) {
                return true;
                return true;
            }
            }
            return canProjectSecureVideo(projection);
            return canProjectSecureVideo(projection);
@@ -2297,9 +2310,17 @@ public final class DisplayManagerService extends SystemService {
                    Slog.e(TAG, "Unable to query projection service for permissions", e);
                    Slog.e(TAG, "Unable to query projection service for permissions", e);
                }
                }
            }
            }
            return mContext.checkCallingPermission(
            return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()");
                    android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
        }
                    == PackageManager.PERMISSION_GRANTED;

        private boolean checkCallingPermission(String permission, String func) {
            if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
                return true;
            }
            final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid() + " requires " + permission;
            Slog.w(TAG, msg);
            return false;
        }
        }
    }
    }