Merge changes from topic 'aia_settings_overlay' into oc-dev

* changes:
  Add overlay for Instant Apps Settings whitelists
  Revert "Allow Instant Apps to read Settings defined by apps"
This commit is contained in:
Chad Brubaker
2017-05-01 22:12:47 +00:00
committed by Android (Google) Code Review
3 changed files with 61 additions and 27 deletions

View File

@@ -2863,4 +2863,13 @@
<!-- The apps that need to be hidden when they are disabled -->
<string-array name="config_hideWhenDisabled_packageNames"></string-array>
<!-- Additional non-platform defined global settings exposed to Instant Apps -->
<string-array name="config_allowedGlobalInstantAppSettings"></string-array>
<!-- Additional non-platform defined system settings exposed to Instant Apps -->
<string-array name="config_allowedSystemInstantAppSettings"></string-array>
<!-- Additional non-platform defined secure settings exposed to Instant Apps -->
<string-array name="config_allowedSecureInstantAppSettings"></string-array>
</resources>

View File

@@ -3003,4 +3003,8 @@
<java-symbol type="string" name="config_feedbackIntentNameKey" />
<java-symbol type="array" name="config_hideWhenDisabled_packageNames" />
<java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
<java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
<java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
</resources>

View File

@@ -35,6 +35,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
@@ -185,6 +186,26 @@ public class SettingsProvider extends ContentProvider {
private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair(
Settings.NameValueTable.VALUE, null);
// Overlay specified settings whitelisted for Instant Apps
private static final Set<String> OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS = new ArraySet<>();
private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>();
static {
for (String name : Resources.getSystem().getStringArray(
com.android.internal.R.array.config_allowedGlobalInstantAppSettings)) {
OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS.add(name);
}
for (String name : Resources.getSystem().getStringArray(
com.android.internal.R.array.config_allowedSystemInstantAppSettings)) {
OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS.add(name);
}
for (String name : Resources.getSystem().getStringArray(
com.android.internal.R.array.config_allowedSecureInstantAppSettings)) {
OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS.add(name);
}
}
// Changes to these global settings are synchronously persisted
private static final Set<String> CRITICAL_GLOBAL_SETTINGS = new ArraySet<>();
static {
@@ -898,14 +919,13 @@ public class SettingsProvider extends ContentProvider {
Slog.v(LOG_TAG, "getGlobalSetting(" + name + ")");
}
// Ensure the caller can access the setting.
enforceSettingReadable(name, SETTINGS_TYPE_GLOBAL, UserHandle.getCallingUserId());
// Get the value.
synchronized (mLock) {
Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_GLOBAL,
return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_GLOBAL,
UserHandle.USER_SYSTEM, name);
// Ensure the caller can access the setting before we return it.
enforceSettingReadable(setting, name, SETTINGS_TYPE_GLOBAL,
UserHandle.getCallingUserId());
return setting;
}
}
@@ -1063,6 +1083,9 @@ public class SettingsProvider extends ContentProvider {
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
// Ensure the caller can access the setting.
enforceSettingReadable(name, SETTINGS_TYPE_SECURE, UserHandle.getCallingUserId());
// Determine the owning user as some profile settings are cloned from the parent.
final int owningUserId = resolveOwningUserIdForSecureSettingLocked(callingUserId, name);
@@ -1076,7 +1099,6 @@ public class SettingsProvider extends ContentProvider {
// As of Android O, the SSAID is read from an app-specific entry in table
// SETTINGS_FILE_SSAID, unless accessed by a system process.
// All apps are allowed to access their SSAID, so we skip the permission check.
if (isNewSsaidSetting(name)) {
PackageInfo callingPkg = getCallingPackageInfo(owningUserId);
synchronized (mLock) {
@@ -1086,12 +1108,8 @@ public class SettingsProvider extends ContentProvider {
// Not the SSAID; do a straight lookup
synchronized (mLock) {
Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE,
return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE,
owningUserId, name);
// Ensure the caller can access the setting before we return it.
enforceSettingReadable(setting, name, SETTINGS_TYPE_SECURE,
UserHandle.getCallingUserId());
return setting;
}
}
@@ -1292,18 +1310,15 @@ public class SettingsProvider extends ContentProvider {
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
// Ensure the caller can access the setting.
enforceSettingReadable(name, SETTINGS_TYPE_SYSTEM, UserHandle.getCallingUserId());
// Determine the owning user as some profile settings are cloned from the parent.
final int owningUserId = resolveOwningUserIdForSystemSettingLocked(callingUserId, name);
// Get the value.
synchronized (mLock) {
Setting setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SYSTEM,
owningUserId, name);
// Ensure the caller can access the setting before we return it.
enforceSettingReadable(setting, name, SETTINGS_TYPE_SYSTEM,
UserHandle.getCallingUserId());
return setting;
return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SYSTEM, owningUserId, name);
}
}
@@ -1635,6 +1650,19 @@ public class SettingsProvider extends ContentProvider {
}
}
private Set<String> getOverlayInstantAppAccessibleSettings(int settingsType) {
switch (settingsType) {
case SETTINGS_TYPE_GLOBAL:
return OVERLAY_ALLOWED_GLOBAL_INSTANT_APP_SETTINGS;
case SETTINGS_TYPE_SYSTEM:
return OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS;
case SETTINGS_TYPE_SECURE:
return OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS;
default:
throw new IllegalArgumentException("Invalid settings type: " + settingsType);
}
}
private List<String> getSettingsNamesLocked(int settingsType, int userId) {
boolean instantApp;
if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
@@ -1650,23 +1678,16 @@ public class SettingsProvider extends ContentProvider {
}
}
private void enforceSettingReadable(Setting setting, String settingName, int settingsType,
int userId) {
private void enforceSettingReadable(String settingName, int settingsType, int userId) {
if (UserHandle.getAppId(Binder.getCallingUid()) < Process.FIRST_APPLICATION_UID) {
return;
}
ApplicationInfo ai = getCallingApplicationInfoOrThrow();
// Installed apps are allowed to read all settings.
if (!ai.isInstantApp()) {
return;
}
// Instant Apps are allowed to read settings defined by applications.
// TODO: Replace this with an API that allows the setting application to say if a setting
// shoud/shouldn't be accessible.
if (!setting.isDefaultFromSystem()) {
return;
}
if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)) {
if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)
&& !getOverlayInstantAppAccessibleSettings(settingsType).contains(settingName)) {
throw new SecurityException("Setting " + settingName + " is not accessible from"
+ " ephemeral package " + getCallingPackage());
}