Loading core/java/android/provider/DeviceConfig.java +40 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ActivityThread; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings.ResetMode; Loading @@ -37,6 +39,7 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -256,6 +259,14 @@ public final class DeviceConfig { @SystemApi public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; /** * List of namespaces which can be read without READ_DEVICE_CONFIG permission * * @hide */ @NonNull private static final List<String> PUBLIC_NAMESPACES = Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME); /** * Privacy related properties definitions. * Loading Loading @@ -527,6 +538,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertyChangedListener onPropertyChangedListener) { enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), namespace); synchronized (sLock) { Pair<String, Executor> oldNamespace = sSingleListeners.get(onPropertyChangedListener); if (oldNamespace == null) { Loading Loading @@ -566,6 +579,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertiesChangedListener onPropertiesChangedListener) { enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), namespace); synchronized (sLock) { Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener); if (oldNamespace == null) { Loading Loading @@ -696,7 +711,14 @@ public final class DeviceConfig { // pathSegments(0) is "config" final String namespace = pathSegments.get(1); final String name = pathSegments.get(2); final String value = getProperty(namespace, name); final String value; try { value = getProperty(namespace, name); } catch (SecurityException e) { // Silently failing to not crash binder or listener threads. Log.e(TAG, "OnPropertyChangedListener update failed: permission violation."); return; } synchronized (sLock) { // OnPropertiesChangedListeners for (int i = 0; i < sListeners.size(); i++) { Loading Loading @@ -730,6 +752,22 @@ public final class DeviceConfig { } } /** * Enforces READ_DEVICE_CONFIG permission if namespace is not one of public namespaces. * @hide */ public static void enforceReadPermission(Context context, String namespace) { if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PackageManager.PERMISSION_GRANTED) { if (!PUBLIC_NAMESPACES.contains(namespace)) { throw new SecurityException("Permission denial: reading from settings requires:" + READ_DEVICE_CONFIG); } } } /** * Interface for monitoring single property changes. * <p> Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +1 −2 Original line number Diff line number Diff line Loading @@ -1074,8 +1074,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "getConfigSetting(" + name + ")"); } // TODO(b/117663715): Ensure the caller can access the setting. // enforceReadPermission(READ_DEVICE_CONFIG); DeviceConfig.enforceReadPermission(getContext(), /*namespace=*/name.split("/")[0]); // Get the value. synchronized (mLock) { Loading Loading
core/java/android/provider/DeviceConfig.java +40 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ActivityThread; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings.ResetMode; Loading @@ -37,6 +39,7 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -256,6 +259,14 @@ public final class DeviceConfig { @SystemApi public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; /** * List of namespaces which can be read without READ_DEVICE_CONFIG permission * * @hide */ @NonNull private static final List<String> PUBLIC_NAMESPACES = Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME); /** * Privacy related properties definitions. * Loading Loading @@ -527,6 +538,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertyChangedListener onPropertyChangedListener) { enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), namespace); synchronized (sLock) { Pair<String, Executor> oldNamespace = sSingleListeners.get(onPropertyChangedListener); if (oldNamespace == null) { Loading Loading @@ -566,6 +579,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertiesChangedListener onPropertiesChangedListener) { enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), namespace); synchronized (sLock) { Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener); if (oldNamespace == null) { Loading Loading @@ -696,7 +711,14 @@ public final class DeviceConfig { // pathSegments(0) is "config" final String namespace = pathSegments.get(1); final String name = pathSegments.get(2); final String value = getProperty(namespace, name); final String value; try { value = getProperty(namespace, name); } catch (SecurityException e) { // Silently failing to not crash binder or listener threads. Log.e(TAG, "OnPropertyChangedListener update failed: permission violation."); return; } synchronized (sLock) { // OnPropertiesChangedListeners for (int i = 0; i < sListeners.size(); i++) { Loading Loading @@ -730,6 +752,22 @@ public final class DeviceConfig { } } /** * Enforces READ_DEVICE_CONFIG permission if namespace is not one of public namespaces. * @hide */ public static void enforceReadPermission(Context context, String namespace) { if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PackageManager.PERMISSION_GRANTED) { if (!PUBLIC_NAMESPACES.contains(namespace)) { throw new SecurityException("Permission denial: reading from settings requires:" + READ_DEVICE_CONFIG); } } } /** * Interface for monitoring single property changes. * <p> Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +1 −2 Original line number Diff line number Diff line Loading @@ -1074,8 +1074,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "getConfigSetting(" + name + ")"); } // TODO(b/117663715): Ensure the caller can access the setting. // enforceReadPermission(READ_DEVICE_CONFIG); DeviceConfig.enforceReadPermission(getContext(), /*namespace=*/name.split("/")[0]); // Get the value. synchronized (mLock) { Loading