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

Commit 638ea6d4 authored by kumarashishg's avatar kumarashishg Committed by Android Build Coastguard Worker
Browse files

Resolve custom printer icon boundary exploit.

Because Settings grants the INTERACT_ACROSS_USERS_FULL permission, an exploit is possible where the third party print plugin service can pass other's User Icon URI. This CL provides a lightweight solution for parsing the image URI to detect profile exploitation.

Bug: 281525042
Test: Build and flash the code. Try to reproduce the issue with
mentioned steps in the bug
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7cfc47271c77b2fa5e9fa05fcf5c315dfb778dec)
Merged-In: Iaaa6fe2a627a265c4d1d7b843a033a132e1fe2ce
Change-Id: Iaaa6fe2a627a265c4d1d7b843a033a132e1fe2ce
parent 4931b2d3
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -254,12 +254,45 @@ public final class PrintManagerService extends SystemService {
            }
            final long identity = Binder.clearCallingIdentity();
            try {
                return userState.getCustomPrinterIcon(printerId);
                Icon icon = userState.getCustomPrinterIcon(printerId);
                return validateIconUserBoundary(icon);
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }

        /**
         * Validates the custom printer icon to see if it's not in the calling user space.
         * If the condition is not met, return null. Otherwise, return the original icon.
         *
         * @param icon
         * @return icon (validated)
         */
        private Icon validateIconUserBoundary(Icon icon) {
            // Refer to Icon#getUriString for context. The URI string is invalid for icons of
            // incompatible types.
            if (icon != null && (icon.getType() == Icon.TYPE_URI
                    || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
                String encodedUser = icon.getUri().getEncodedUserInfo();

                // If there is no encoded user, the URI is calling into the calling user space
                if (encodedUser != null) {
                    int userId = Integer.parseInt(encodedUser);
                    // resolve encoded user
                    final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);

                    synchronized (mLock) {
                        // Only the current group members can get the printer icons.
                        if (resolveCallingProfileParentLocked(resolvedUserId)
                                != getCurrentUserId()) {
                            return null;
                        }
                    }
                }
            }
            return icon;
        }

        @Override
        public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
            if (printJobId == null) {