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

Commit 030e593b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Refactor the installer name verification so that we do not crash on...

Merge "Refactor the installer name verification so that we do not crash on Android Auto where the UID can change depending on the user." into rvc-dev am: 34ef20fa am: 2766d367

Change-Id: Ia02fb494b1e332f1dbef0367359573bc4c2e0e02
parents 74212421 2766d367
Loading
Loading
Loading
Loading
+68 −62
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import static android.content.integrity.InstallerAllowedByManifestFormula.INSTAL
import static android.content.integrity.IntegrityUtils.getHexDigest;
import static android.content.integrity.IntegrityUtils.getHexDigest;
import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;


import android.annotation.BinderThread;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
@@ -50,7 +51,6 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Slog;
import android.util.Slog;
@@ -89,9 +89,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Set;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.Stream;
import java.util.function.Supplier;


/** Implementation of {@link AppIntegrityManagerService}. */
/** Implementation of {@link AppIntegrityManagerService}. */
public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
@@ -184,9 +184,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
    }
    }


    @Override
    @Override
    @BinderThread
    public void updateRuleSet(
    public void updateRuleSet(
            String version, ParceledListSlice<Rule> rules, IntentSender statusReceiver) {
            String version, ParceledListSlice<Rule> rules, IntentSender statusReceiver) {
        String ruleProvider = getCallerPackageNameOrThrow();
        String ruleProvider = getCallerPackageNameOrThrow(Binder.getCallingUid());


        mHandler.post(
        mHandler.post(
                () -> {
                () -> {
@@ -220,8 +221,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
    }
    }


    @Override
    @Override
    @BinderThread
    public String getCurrentRuleSetVersion() {
    public String getCurrentRuleSetVersion() {
        getCallerPackageNameOrThrow();
        getCallerPackageNameOrThrow(Binder.getCallingUid());


        RuleMetadata ruleMetadata = mIntegrityFileManager.readMetadata();
        RuleMetadata ruleMetadata = mIntegrityFileManager.readMetadata();
        return (ruleMetadata != null && ruleMetadata.getVersion() != null)
        return (ruleMetadata != null && ruleMetadata.getVersion() != null)
@@ -230,8 +232,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
    }
    }


    @Override
    @Override
    @BinderThread
    public String getCurrentRuleSetProvider() {
    public String getCurrentRuleSetProvider() {
        getCallerPackageNameOrThrow();
        getCallerPackageNameOrThrow(Binder.getCallingUid());


        RuleMetadata ruleMetadata = mIntegrityFileManager.readMetadata();
        RuleMetadata ruleMetadata = mIntegrityFileManager.readMetadata();
        return (ruleMetadata != null && ruleMetadata.getRuleProvider() != null)
        return (ruleMetadata != null && ruleMetadata.getRuleProvider() != null)
@@ -251,8 +254,8 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
    }
    }


    @Override
    @Override
    public List<String> getWhitelistedRuleProviders() throws RemoteException {
    public List<String> getWhitelistedRuleProviders() {
        return getAllowedRuleProviders();
        return getAllowedRuleProviderSystemApps();
    }
    }


    private void handleIntegrityVerification(Intent intent) {
    private void handleIntegrityVerification(Intent intent) {
@@ -367,23 +370,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
            return UNKNOWN_INSTALLER;
            return UNKNOWN_INSTALLER;
        }
        }


        try {
        // Verify that the installer UID actually contains the package. Note that comparing UIDs
            int actualInstallerUid =
        // is not safe since context's uid can change in different settings; e.g. Android Auto.
                    mContext.getPackageManager().getPackageUid(installer, /* flags= */ 0);
        if (!getPackageListForUid(installerUid).contains(installer)) {
            if (actualInstallerUid != installerUid) {
                // Installer package name can be faked but the installerUid cannot.
                Slog.e(
                        TAG,
                        "Installer "
                                + installer
                                + " has UID "
                                + actualInstallerUid
                                + " which doesn't match alleged installer UID "
                                + installerUid);
                return UNKNOWN_INSTALLER;
            }
        } catch (PackageManager.NameNotFoundException e) {
            Slog.e(TAG, "Installer package " + installer + " not found.");
            return UNKNOWN_INSTALLER;
            return UNKNOWN_INSTALLER;
        }
        }


@@ -398,14 +387,13 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
                Slog.e(TAG, "Installer is package installer but originating UID not found.");
                Slog.e(TAG, "Installer is package installer but originating UID not found.");
                return UNKNOWN_INSTALLER;
                return UNKNOWN_INSTALLER;
            }
            }
            String[] installerPackages =
            List<String> installerPackages = getPackageListForUid(originatingUid);
                    mContext.getPackageManager().getPackagesForUid(originatingUid);
            if (installerPackages.isEmpty()) {
            if (installerPackages == null || installerPackages.length == 0) {
                Slog.e(TAG, "No package found associated with originating UID " + originatingUid);
                Slog.e(TAG, "No package found associated with originating UID " + originatingUid);
                return UNKNOWN_INSTALLER;
                return UNKNOWN_INSTALLER;
            }
            }
            // In the case of multiple package sharing a UID, we just return the first one.
            // In the case of multiple package sharing a UID, we just return the first one.
            return installerPackages[0];
            return installerPackages.get(0);
        }
        }


        return installer;
        return installer;
@@ -652,8 +640,8 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
        return installationPath;
        return installationPath;
    }
    }


    private String getCallerPackageNameOrThrow() {
    private String getCallerPackageNameOrThrow(int callingUid) {
        String callerPackageName = getCallerPackageName();
        String callerPackageName = getCallingRulePusherPackageName(callingUid);
        if (callerPackageName == null) {
        if (callerPackageName == null) {
            throw new SecurityException(
            throw new SecurityException(
                    "Only system packages specified in config_integrityRuleProviderPackages are "
                    "Only system packages specified in config_integrityRuleProviderPackages are "
@@ -662,25 +650,45 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
        return callerPackageName;
        return callerPackageName;
    }
    }


    private String getCallerPackageName() {
    private String getCallingRulePusherPackageName(int callingUid) {
        final List<String> allowedRuleProviders = getAllowedRuleProviders();
        // Obtain the system apps that are whitelisted in config_integrityRuleProviderPackages.
        for (String packageName : allowedRuleProviders) {
        List<String> allowedRuleProviders = getAllowedRuleProviderSystemApps();
            try {
        Slog.i(TAG, String.format(
                // At least in tests, getPackageUid gives "NameNotFound" but getPackagesFromUid
                "Rule provider system app list contains: %s", allowedRuleProviders));
                // give the correct package name.

                int uid = mContext.getPackageManager().getPackageUid(packageName, 0);
        // Identify the package names in the caller list.
                if (uid == Binder.getCallingUid()) {
        List<String> callingPackageNames = getPackageListForUid(callingUid);
                    // Caller is allowed in the config.
        Slog.i(TAG, String.format("Calling packages are: ", callingPackageNames));
                    if (isSystemApp(packageName)) {

                        return packageName;
        // Find the intersection between the allowed and calling packages. Ideally, we will have
                    }
        // at most one package name here. But if we have more, it is fine.
                }
        List<String> allowedCallingPackages =
            } catch (PackageManager.NameNotFoundException e) {
                callingPackageNames
                // Ignore the exception. We don't expect the app to be necessarily installed.
                        .stream()
                Slog.i(TAG, "Rule provider package " + packageName + " not installed.");
                        .filter(packageName -> allowedRuleProviders.contains(packageName))
                        .collect(Collectors.toList());
        Slog.i(TAG, String.format("Calling rule pusher packages are: ", allowedCallingPackages));

        return allowedCallingPackages.isEmpty() ? null : allowedCallingPackages.get(0);
    }
    }

    private boolean isRuleProvider(String installerPackageName) {
        return getAllowedRuleProviderSystemApps().stream()
                .anyMatch(ruleProvider -> ruleProvider.equals(installerPackageName));
    }
    }
        return null;

    private List<String> getAllowedRuleProviderSystemApps() {
        List<String> integrityRuleProviders =
                Arrays.asList(
                        mContext.getResources()
                                .getStringArray(R.array.config_integrityRuleProviderPackages));

        Slog.i(TAG, String.format("Rule provider list contains: %s", integrityRuleProviders));

        // Filter out the rule provider packages that are not system apps.
        return integrityRuleProviders.stream()
                .filter(this::isSystemApp)
                .collect(Collectors.toList());
    }
    }


    private boolean isSystemApp(String packageName) {
    private boolean isSystemApp(String packageName) {
@@ -694,17 +702,6 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
        }
        }
    }
    }


    private List<String> getAllowedRuleProviders() {
        return Arrays.asList(
                mContext.getResources()
                        .getStringArray(R.array.config_integrityRuleProviderPackages));
    }

    private boolean isRuleProvider(String installerPackageName) {
        return getAllowedRuleProviders().stream()
                .anyMatch(ruleProvider -> ruleProvider.equals(installerPackageName));
    }

    private boolean integrityCheckIncludesRuleProvider() {
    private boolean integrityCheckIncludesRuleProvider() {
        return Settings.Global.getInt(
        return Settings.Global.getInt(
                        mContext.getContentResolver(),
                        mContext.getContentResolver(),
@@ -712,4 +709,13 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
                        0)
                        0)
                == 1;
                == 1;
    }
    }

    private List<String> getPackageListForUid(int uid) {
        try {
            return Arrays.asList(mContext.getPackageManager().getPackagesForUid(uid));
        } catch (NullPointerException e) {
            Slog.w(TAG, String.format("No packages were found for uid: %d", uid));
            return List.of();
        }
    }
}
}
+10 −0
Original line number Original line Diff line number Diff line
@@ -488,9 +488,18 @@ public class AppIntegrityManagerServiceImplTest {
        assertThat(mService.getCurrentRules().getList()).containsExactly(rule);
        assertThat(mService.getCurrentRules().getList()).containsExactly(rule);
    }
    }


    @Test
    public void getWhitelistedRuleProviders_returnsEmptyForNonSystemApps() throws Exception {
        whitelistUsAsRuleProvider();
        makeUsSystemApp(false);

        assertThat(mService.getWhitelistedRuleProviders()).isEmpty();
    }

    @Test
    @Test
    public void getWhitelistedRuleProviders() throws Exception {
    public void getWhitelistedRuleProviders() throws Exception {
        whitelistUsAsRuleProvider();
        whitelistUsAsRuleProvider();
        makeUsSystemApp();


        assertThat(mService.getWhitelistedRuleProviders()).containsExactly(TEST_FRAMEWORK_PACKAGE);
        assertThat(mService.getWhitelistedRuleProviders()).containsExactly(TEST_FRAMEWORK_PACKAGE);
    }
    }
@@ -535,6 +544,7 @@ public class AppIntegrityManagerServiceImplTest {
                                TEST_FRAMEWORK_PACKAGE, PackageManager.GET_SIGNING_CERTIFICATES);
                                TEST_FRAMEWORK_PACKAGE, PackageManager.GET_SIGNING_CERTIFICATES);
        doReturn(packageInfo).when(mSpyPackageManager).getPackageInfo(eq(INSTALLER), anyInt());
        doReturn(packageInfo).when(mSpyPackageManager).getPackageInfo(eq(INSTALLER), anyInt());
        doReturn(1).when(mSpyPackageManager).getPackageUid(eq(INSTALLER), anyInt());
        doReturn(1).when(mSpyPackageManager).getPackageUid(eq(INSTALLER), anyInt());
        doReturn(new String[]{INSTALLER}).when(mSpyPackageManager).getPackagesForUid(anyInt());
        return makeVerificationIntent(INSTALLER);
        return makeVerificationIntent(INSTALLER);
    }
    }