Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +24 −12 Original line number Diff line number Diff line Loading @@ -2434,28 +2434,40 @@ public class SettingsProvider extends ContentProvider { context.checkCallingOrSelfPermission( Manifest.permission.WRITE_DEVICE_CONFIG) == PackageManager.PERMISSION_GRANTED; boolean isRoot = Binder.getCallingUid() == Process.ROOT_UID; // Only the shell user and tests request the allowlist permission; this is used to force // the WRITE_ALLOWLISTED_DEVICE_CONFIG path to log any flags that need to be allowlisted. boolean isRestrictedShell = android.security.Flags.protectDeviceConfigFlags() && hasAllowlistPermission; if (isRoot) { return; } if (hasWritePermission) { if (!isRestrictedShell && hasWritePermission) { assertCallingUserDenyList(flags); } else if (hasAllowlistPermission) { for (String flag : flags) { boolean namespaceAllowed = false; if (isRestrictedShell) { int delimiterIndex = flag.indexOf("/"); String flagNamespace; if (delimiterIndex != -1) { flagNamespace = flag.substring(0, delimiterIndex); } else { flagNamespace = flag; } if (WritableNamespaces.ALLOWLIST.contains(flagNamespace)) { namespaceAllowed = true; } } else { for (String allowlistedPrefix : WritableNamespacePrefixes.ALLOWLIST) { if (flag.startsWith(allowlistedPrefix)) { namespaceAllowed = true; break; } } } if (!namespaceAllowed && !DeviceConfig.getAdbWritableFlags().contains(flag)) { throw new SecurityException("Permission denial for flag '" + flag + "'; allowlist permission granted, but must add flag to the allowlist."); Slog.wtf(LOG_TAG, "Permission denial for flag '" + flag + "'; allowlist permission granted, but must add flag to the " + "allowlist"); } } assertCallingUserDenyList(flags); Loading packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.providers.settings; import android.util.ArraySet; import java.util.Arrays; import java.util.Set; /** * Contains the list of namespaces in which any flag can be written by adb without root * permissions. * <p> * A security review is required for any namespace that's added to this list. To add to * the list, create a change and tag the OWNER. In the commit message, include a * description of the flag's functionality, and a justification for why it needs to be * allowlisted. */ final class WritableNamespaces { public static final Set<String> ALLOWLIST = new ArraySet<String>(Arrays.asList( "exo" )); } Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +24 −12 Original line number Diff line number Diff line Loading @@ -2434,28 +2434,40 @@ public class SettingsProvider extends ContentProvider { context.checkCallingOrSelfPermission( Manifest.permission.WRITE_DEVICE_CONFIG) == PackageManager.PERMISSION_GRANTED; boolean isRoot = Binder.getCallingUid() == Process.ROOT_UID; // Only the shell user and tests request the allowlist permission; this is used to force // the WRITE_ALLOWLISTED_DEVICE_CONFIG path to log any flags that need to be allowlisted. boolean isRestrictedShell = android.security.Flags.protectDeviceConfigFlags() && hasAllowlistPermission; if (isRoot) { return; } if (hasWritePermission) { if (!isRestrictedShell && hasWritePermission) { assertCallingUserDenyList(flags); } else if (hasAllowlistPermission) { for (String flag : flags) { boolean namespaceAllowed = false; if (isRestrictedShell) { int delimiterIndex = flag.indexOf("/"); String flagNamespace; if (delimiterIndex != -1) { flagNamespace = flag.substring(0, delimiterIndex); } else { flagNamespace = flag; } if (WritableNamespaces.ALLOWLIST.contains(flagNamespace)) { namespaceAllowed = true; } } else { for (String allowlistedPrefix : WritableNamespacePrefixes.ALLOWLIST) { if (flag.startsWith(allowlistedPrefix)) { namespaceAllowed = true; break; } } } if (!namespaceAllowed && !DeviceConfig.getAdbWritableFlags().contains(flag)) { throw new SecurityException("Permission denial for flag '" + flag + "'; allowlist permission granted, but must add flag to the allowlist."); Slog.wtf(LOG_TAG, "Permission denial for flag '" + flag + "'; allowlist permission granted, but must add flag to the " + "allowlist"); } } assertCallingUserDenyList(flags); Loading
packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.providers.settings; import android.util.ArraySet; import java.util.Arrays; import java.util.Set; /** * Contains the list of namespaces in which any flag can be written by adb without root * permissions. * <p> * A security review is required for any namespace that's added to this list. To add to * the list, create a change and tag the OWNER. In the commit message, include a * description of the flag's functionality, and a justification for why it needs to be * allowlisted. */ final class WritableNamespaces { public static final Set<String> ALLOWLIST = new ArraySet<String>(Arrays.asList( "exo" )); }