Loading core/res/res/values/config.xml +9 −0 Original line number Diff line number Diff line Loading @@ -2877,4 +2877,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> core/res/res/values/symbols.xml +4 −0 Original line number Diff line number Diff line Loading @@ -3015,4 +3015,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> packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +48 −27 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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; } } Loading Loading @@ -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); Loading @@ -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) { Loading @@ -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; } } Loading Loading @@ -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); } } Loading Loading @@ -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) { Loading @@ -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()); } Loading Loading
core/res/res/values/config.xml +9 −0 Original line number Diff line number Diff line Loading @@ -2877,4 +2877,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>
core/res/res/values/symbols.xml +4 −0 Original line number Diff line number Diff line Loading @@ -3015,4 +3015,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>
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +48 −27 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading @@ -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; } } Loading Loading @@ -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); Loading @@ -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) { Loading @@ -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; } } Loading Loading @@ -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); } } Loading Loading @@ -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) { Loading @@ -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()); } Loading