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."

This commit is contained in:
TreeHugger Robot
2020-04-16 17:15:40 +00:00
committed by Android (Google) Code Review
2 changed files with 55 additions and 40 deletions

View File

@@ -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.");
}
}
return null;
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));
}
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(),

View File

@@ -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);
}