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

Commit 6282dc52 authored by Rhed Jao's avatar Rhed Jao Committed by Android (Google) Code Review
Browse files

Merge changes from topic "pm_cross_user_package_visibility_6"

* changes:
  Using isUidPrivileged instead of getPrivateFlagsForUid API
  Add package manager internal api checkUidSignaturesForAllUsers
  Fix cross user package visibility leakage for PackageManager (6/n)
parents 3c4c1870 87944e74
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.UserHandle;
import android.util.ArraySet;
@@ -32,6 +33,7 @@ import android.util.DebugUtils;
import android.util.IndentingPrintWriter;

import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -108,7 +110,7 @@ class BlobAccessMode {
        }

        if ((mAccessType & ACCESS_TYPE_SAME_SIGNATURE) != 0) {
            if (checkSignatures(context, callingUid, committerUid)) {
            if (checkSignatures(callingUid, committerUid)) {
                return true;
            }
        }
@@ -133,11 +135,11 @@ class BlobAccessMode {
    /**
     * Compare signatures for two packages of different users.
     */
    private boolean checkSignatures(Context context, int uid1, int uid2) {
    private boolean checkSignatures(int uid1, int uid2) {
        final long token = Binder.clearCallingIdentity();
        try {
            return context.getPackageManager().checkSignatures(uid1, uid2)
                    == PackageManager.SIGNATURE_MATCH;
            return LocalServices.getService(PackageManagerInternal.class)
                    .checkUidSignaturesForAllUsers(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
+12 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager.SignatureResult;
import android.content.pm.SigningDetails.CertCapabilities;
import android.content.pm.overlay.OverlayPaths;
import android.os.Bundle;
@@ -1283,4 +1284,15 @@ public abstract class PackageManagerInternal {
    public abstract void shutdown();

    public abstract DynamicCodeLogger getDynamicCodeLogger();

    /**
     * Compare the signatures of two packages that are installed in different users.
     *
     * @param uid1 First UID whose signature will be compared.
     * @param uid2 Second UID whose signature will be compared.
     * @return {@link PackageManager#SIGNATURE_MATCH} if signatures are matched.
     * @throws SecurityException if the caller does not hold the
     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS}.
     */
    public abstract @SignatureResult int checkUidSignaturesForAllUsers(int uid1, int uid2);
}
+8 −6
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
@@ -129,7 +130,7 @@ public class IntentFirewall {
        mObserver.startWatching();
    }

    private PackageManagerInternal getPackageManager() {
    PackageManagerInternal getPackageManager() {
        if (mPackageManager == null) {
            mPackageManager = LocalServices.getService(PackageManagerInternal.class);
        }
@@ -623,12 +624,13 @@ public class IntentFirewall {
    }

    boolean signaturesMatch(int uid1, int uid2) {
        final long token = Binder.clearCallingIdentity();
        try {
            IPackageManager pm = AppGlobals.getPackageManager();
            return pm.checkUidSignatures(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
        } catch (RemoteException ex) {
            Slog.e(TAG, "Remote exception while checking signatures", ex);
            return false;
            // Compare signatures of two packages for different users.
            return getPackageManager()
                    .checkUidSignaturesForAllUsers(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

+7 −20
Original line number Diff line number Diff line
@@ -16,14 +16,11 @@

package com.android.server.firewall;

import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Process;
import android.os.RemoteException;
import android.util.Slog;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

@@ -37,22 +34,12 @@ class SenderFilter {
    private static final String VAL_SYSTEM_OR_SIGNATURE = "system|signature";
    private static final String VAL_USER_ID = "userId";

    static boolean isPrivilegedApp(int callerUid, int callerPid) {
    static boolean isPrivilegedApp(PackageManagerInternal pmi, int callerUid, int callerPid) {
        if (callerUid == Process.SYSTEM_UID || callerUid == 0 ||
                callerPid == Process.myPid() || callerPid == 0) {
            return true;
        }

        IPackageManager pm = AppGlobals.getPackageManager();
        try {
            return (pm.getPrivateFlagsForUid(callerUid) & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
                    != 0;
        } catch (RemoteException ex) {
            Slog.e(IntentFirewall.TAG, "Remote exception while retrieving uid flags",
                    ex);
        }

        return false;
        return pmi.isUidPrivileged(callerUid);
    }

    public static final FilterFactory FACTORY = new FilterFactory("sender") {
@@ -89,7 +76,7 @@ class SenderFilter {
        @Override
        public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
                int callerUid, int callerPid, String resolvedType, int receivingUid) {
            return isPrivilegedApp(callerUid, callerPid);
            return isPrivilegedApp(ifw.getPackageManager(), callerUid, callerPid);
        }
    };

@@ -97,8 +84,8 @@ class SenderFilter {
        @Override
        public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
                int callerUid, int callerPid, String resolvedType, int receivingUid) {
            return isPrivilegedApp(callerUid, callerPid) ||
                    ifw.signaturesMatch(callerUid, receivingUid);
            return isPrivilegedApp(ifw.getPackageManager(), callerUid, callerPid)
                    || ifw.signaturesMatch(callerUid, receivingUid);
        }
    };

+22 −0
Original line number Diff line number Diff line
@@ -228,8 +228,28 @@ public interface Computer extends PackageDataSnapshot {
            int userId);
    boolean shouldFilterApplication(@NonNull SharedUserSetting sus, int callingUid,
            int userId);
    /**
     * Different form {@link #shouldFilterApplication(PackageStateInternal, int, int)}, the function
     * returns {@code true} if the target package is not found in the device or uninstalled in the
     * current user. Unless the caller's function needs to handle the package's uninstalled state
     * by itself, using this function to keep the consistent behavior between conditions of package
     * uninstalled and visibility not allowed to avoid the side channel leakage of package
     * existence.
     * <p>
     * Package with {@link PackageManager#SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN} is not
     * treated as an uninstalled package for the carrier apps customization.
     */
    boolean shouldFilterApplicationIncludingUninstalled(@Nullable PackageStateInternal ps,
            int callingUid, int userId);
    /**
     * Different from {@link #shouldFilterApplication(SharedUserSetting, int, int)}, the function
     * returns {@code true} if packages with the same shared user are all uninstalled in the current
     * user.
     *
     * @see #shouldFilterApplicationIncludingUninstalled(PackageStateInternal, int, int)
     */
    boolean shouldFilterApplicationIncludingUninstalled(@NonNull SharedUserSetting sus,
            int callingUid, int userId);
    int checkUidPermission(String permName, int uid);
    int getPackageUidInternal(String packageName, long flags, int userId, int callingUid);
    long updateFlagsForApplication(long flags, int userId);
@@ -378,6 +398,8 @@ public interface Computer extends PackageDataSnapshot {

    int checkUidSignatures(int uid1, int uid2);

    int checkUidSignaturesForAllUsers(int uid1, int uid2);

    boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
            @PackageManager.CertificateInputType int type);

Loading