Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 052518f8 authored by Stanislav Zholnin's avatar Stanislav Zholnin Committed by Android (Google) Code Review
Browse files

Merge "Add READ_DEVICE_CONFIG permission check to DeviceConfig API."

parents 95d2c302 5579950a
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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.
     *
@@ -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) {
@@ -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) {
@@ -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++) {
@@ -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>
+1 −2
Original line number Diff line number Diff line
@@ -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) {