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

Commit 670d0cdb authored by Nathan Muggli's avatar Nathan Muggli Committed by Android Build Coastguard Worker
Browse files

print: Prevent cross-user icon access

A specially crafted URI could cause Uri.getEncodedUserInfo to return an
incorrect value.  Instead, use the more robust getUserIdFromAuthority.

Additionally, refactored this check slightly to address a few previous
CL comments.

Bug: 376462130
Test: Manual test using steps from bug
Flag: EXEMPT BUGFIX
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:8d40513846ee77a70f17e392ef9a9fc4ac254e44
Merged-In: I020c64c8dd1b755877826c7fc7dadecae98dd5f4
Change-Id: I020c64c8dd1b755877826c7fc7dadecae98dd5f4
parent c13fdd4f
Loading
Loading
Loading
Loading
+9 −15
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
@@ -255,7 +256,7 @@ public final class PrintManagerService extends SystemService {
            final long identity = Binder.clearCallingIdentity();
            final long identity = Binder.clearCallingIdentity();
            try {
            try {
                Icon icon = userState.getCustomPrinterIcon(printerId);
                Icon icon = userState.getCustomPrinterIcon(printerId);
                return validateIconUserBoundary(icon);
                return validateIconUserBoundary(icon, resolvedUserId);
            } finally {
            } finally {
                Binder.restoreCallingIdentity(identity);
                Binder.restoreCallingIdentity(identity);
            }
            }
@@ -268,28 +269,21 @@ public final class PrintManagerService extends SystemService {
         * @param icon
         * @param icon
         * @return icon (validated)
         * @return icon (validated)
         */
         */
        private Icon validateIconUserBoundary(Icon icon) {
        private Icon validateIconUserBoundary(Icon icon, int resolvedCallingId) {
            // Refer to Icon#getUriString for context. The URI string is invalid for icons of
            // Refer to Icon#getUriString for context. The URI string is invalid for icons of
            // incompatible types.
            // incompatible types.
            if (icon != null && (icon.getType() == Icon.TYPE_URI
            if (icon != null && (icon.getType() == Icon.TYPE_URI
                    || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
                    || 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);


                final int iconUserId = ContentProvider.getUserIdFromAuthority(
                        icon.getUri().getAuthority(), resolvedCallingId);
                synchronized (mLock) {
                synchronized (mLock) {
                    // Only the current group members can get the printer icons.
                    // Only the current group members can get the printer icons.
                        if (resolveCallingProfileParentLocked(resolvedUserId)
                    if (resolveCallingProfileParentLocked(iconUserId) != getCurrentUserId()) {
                                != getCurrentUserId()) {
                        return null;
                        return null;
                    }
                    }
                }
                }
            }
            }
            }
            return icon;
            return icon;
        }
        }