diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index 35cd9309144e4..6ecdef72acd90 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -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 getWhitelistedRuleProviders() throws RemoteException { - return getAllowedRuleProviders(); + public List 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 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."); - } - } - return null; + private String getCallingRulePusherPackageName() { + // Obtain the system apps that are whitelisted in config_integrityRuleProviderPackages. + List allowedRuleProviders = getAllowedRuleProviderSystemApps(); + Slog.i(TAG, String.format( + "Rule provider system app list contains: %s", allowedRuleProviders)); + + // Identify the package names in the caller list. + List 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 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)); + } + + private List getAllowedRuleProviderSystemApps() { + List 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 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(), diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java index e5741ee1a384c..be4758075fda9 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java @@ -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); }