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

Commit fa4cba2d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor the process of checking whether the calling package for rule...

Merge "Refactor the process of checking whether the calling package for rule update mechanism is a whitelisted system app. The new flow filters out the packages that are not system apps."
parents 24f0fdb2 c1cb1f5d
Loading
Loading
Loading
Loading
+46 −40
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
@@ -251,8 +250,8 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
    }

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

    private void handleIntegrityVerification(Intent intent) {
@@ -653,38 +652,56 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
    }

    private String getCallerPackageNameOrThrow() {
        String callerPackageName = getCallerPackageName();
        String callerPackageName = getCallingRulePusherPackageName();
        if (callerPackageName == null) {
            throw new SecurityException(
                    String.format(
                            "Only system packages specified in config_integrityRuleProviderPackages"
                                    + " are allowed to call this method. These packages are %s.",
                            getAllowedRuleProviders().toString()));
                    "Only system packages specified in config_integrityRuleProviderPackages are "
                            + "allowed to call this method.");
        }
        return callerPackageName;
    }

    private String getCallerPackageName() {
        final List<String> allowedRuleProviders = getAllowedRuleProviders();
        for (String packageName : allowedRuleProviders) {
            try {
                // At least in tests, getPackageUid gives "NameNotFound" but getPackagesFromUid
                // give the correct package name.
                int uid = mContext.getPackageManager().getPackageUid(packageName, 0);
                if (uid == Binder.getCallingUid()) {
                    // Caller is allowed in the config.
                    if (isSystemApp(packageName)) {
                        return packageName;
                    }
                    Slog.i(TAG, "Rule provider package " + packageName + " is not a system app.");
                }
                Slog.i(TAG, "Package " + packageName + " is not among calling package list.");
            } catch (PackageManager.NameNotFoundException e) {
                // Ignore the exception. We don't expect the app to be necessarily installed.
                Slog.i(TAG, "Rule provider package " + packageName + " not installed.");
    private String getCallingRulePusherPackageName() {
        // Obtain the system apps that are whitelisted in config_integrityRuleProviderPackages.
        List<String> allowedRuleProviders = getAllowedRuleProviderSystemApps();
        Slog.i(TAG, String.format(
                "Rule provider system app list contains: %s", allowedRuleProviders));

        // Identify the package names in the caller list.
        List<String> callingPackageNames =
                Arrays.asList(
                        mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid()));
        Slog.i(TAG, String.format("Calling packages are: ", callingPackageNames));

        // 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 =
                callingPackageNames
                        .stream()
                        .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) {
@@ -698,17 +715,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() {
        return Settings.Global.getInt(
                        mContext.getContentResolver(),
+9 −0
Original line number Diff line number Diff line
@@ -488,9 +488,18 @@ public class AppIntegrityManagerServiceImplTest {
        assertThat(mService.getCurrentRules().getList()).containsExactly(rule);
    }

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

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

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

        assertThat(mService.getWhitelistedRuleProviders()).containsExactly(TEST_FRAMEWORK_PACKAGE);
    }