Merge "Add ALLOWLISTED_WRITE_DEVICE_CONFIG permission." into udc-dev am: 52bf203396 am: 80d76d1f12

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21905500

Change-Id: I250ff2966cfc355bf089d9483cb3744bee79565e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Ted Bauer
2023-03-09 19:43:10 +00:00
committed by Automerger Merge Worker
6 changed files with 79 additions and 12 deletions

View File

@@ -33,6 +33,7 @@ package android {
field public static final String ADD_TRUSTED_DISPLAY = "android.permission.ADD_TRUSTED_DISPLAY";
field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY";
field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
field public static final String ALLOWLISTED_WRITE_DEVICE_CONFIG = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG";
field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK";
field public static final String ALLOW_PLACE_IN_MULTI_PANE_SETTINGS = "android.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS";
field public static final String ALLOW_SLIPPERY_TOUCHES = "android.permission.ALLOW_SLIPPERY_TOUCHES";
@@ -287,6 +288,7 @@ package android {
field public static final String READ_SYSTEM_UPDATE_INFO = "android.permission.READ_SYSTEM_UPDATE_INFO";
field public static final String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL";
field public static final String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL";
field public static final String READ_WRITE_SYNC_DISABLED_MODE_CONFIG = "android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG";
field public static final String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS";
field public static final String RECEIVE_BLUETOOTH_MAP = "android.permission.RECEIVE_BLUETOOTH_MAP";
field public static final String RECEIVE_DATA_ACTIVITY_CHANGE = "android.permission.RECEIVE_DATA_ACTIVITY_CHANGE";

View File

@@ -5,6 +5,7 @@ package android {
field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY";
field public static final String ALLOWLISTED_WRITE_DEVICE_CONFIG = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG";
field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS";
field public static final String BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA";
field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE";
@@ -39,6 +40,7 @@ package android {
field public static final String QUERY_AUDIO_STATE = "android.permission.QUERY_AUDIO_STATE";
field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
field public static final String READ_WRITE_SYNC_DISABLED_MODE_CONFIG = "android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG";
field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
field public static final String REMAP_MODIFIER_KEYS = "android.permission.REMAP_MODIFIER_KEYS";
field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";

View File

@@ -4203,6 +4203,16 @@
<permission android:name="android.permission.WRITE_DEVICE_CONFIG"
android:protectionLevel="signature|verifier|configurator"/>
<!-- @SystemApi @TestApi @hide Allows an application to read/write sync disabled mode config.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG"
android:protectionLevel="signature|verifier|configurator"/>
<!-- @SystemApi @TestApi @hide Allows an application to modify only allowlisted settings.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG"
android:protectionLevel="signature|verifier|configurator"/>
<!-- @SystemApi @hide Allows an application to read config settings.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.READ_DEVICE_CONFIG"

View File

@@ -1173,7 +1173,7 @@ public class SettingsProvider extends ContentProvider {
Slog.v(LOG_TAG, "setAllConfigSettings for prefix: " + prefix);
}
enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
enforceDeviceConfigWritePermission(getContext(), keyValues.keySet());
final String callingPackage = resolveCallingPackage();
synchronized (mLock) {
@@ -1192,7 +1192,8 @@ public class SettingsProvider extends ContentProvider {
Slog.v(LOG_TAG, "setSyncDisabledModeConfig(" + syncDisabledMode + ")");
}
enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG,
Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG);
synchronized (mLock) {
setSyncDisabledModeConfigLocked(syncDisabledMode);
@@ -1204,7 +1205,8 @@ public class SettingsProvider extends ContentProvider {
Slog.v(LOG_TAG, "getSyncDisabledModeConfig");
}
enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG,
Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG);
synchronized (mLock) {
return getSyncDisabledModeConfigLocked();
@@ -1289,13 +1291,13 @@ public class SettingsProvider extends ContentProvider {
private boolean mutateConfigSetting(String name, String value, String prefix,
boolean makeDefault, int operation, int mode) {
enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG);
final String callingPackage = resolveCallingPackage();
// Perform the mutation.
synchronized (mLock) {
switch (operation) {
case MUTATION_OPERATION_INSERT: {
enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name));
return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
UserHandle.USER_SYSTEM, name, value, null, makeDefault, true,
callingPackage, false, null,
@@ -1303,11 +1305,14 @@ public class SettingsProvider extends ContentProvider {
}
case MUTATION_OPERATION_DELETE: {
enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name));
return mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_CONFIG,
UserHandle.USER_SYSTEM, name, false, null);
}
case MUTATION_OPERATION_RESET: {
enforceDeviceConfigWritePermission(getContext(),
getAllConfigFlags(prefix).keySet());
mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG,
UserHandle.USER_SYSTEM, callingPackage, mode, null, prefix);
} return true;
@@ -1464,7 +1469,7 @@ public class SettingsProvider extends ContentProvider {
boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
int mode, boolean overrideableByRestore) {
// Make sure the caller can change the settings - treated as secure.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
@@ -1752,7 +1757,7 @@ public class SettingsProvider extends ContentProvider {
boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
int mode, boolean overrideableByRestore) {
// Make sure the caller can change the settings.
enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
// Resolve the userId on whose behalf the call is made.
final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
@@ -2277,11 +2282,57 @@ public class SettingsProvider extends ContentProvider {
}
}
private void enforceWritePermission(String permission) {
if (getContext().checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Permission denial: writing to settings requires:"
+ permission);
private void enforceHasAtLeastOnePermission(String ...permissions) {
for (String permission : permissions) {
if (getContext().checkCallingOrSelfPermission(permission)
== PackageManager.PERMISSION_GRANTED) {
return;
}
}
throw new SecurityException("Permission denial, must have one of: "
+ Arrays.toString(permissions));
}
/**
* Throws an exception if write permissions are not granted for {@code flags}.
* <p>
* Write permissions are granted if the calling UID is root, or the
* WRITE_DEVICE_CONFIG permission is granted, or the WRITE_DEVICE_CONFIG_ALLOWLIST
* permission is granted and each flag in {@code flags} is allowlisted in {@code
* WRITABLE_FLAG_ALLOWLIST_FLAG}.
*
* @param context the {@link Context} this is called in
* @param flags a list of flags to check, each one of the form 'namespace/flagName'
*
* @throws SecurityException if the above criteria are not met.
* @hide
*/
private void enforceDeviceConfigWritePermission(
@NonNull Context context,
@NonNull Set<String> flags) {
boolean hasAllowlistPermission =
context.checkCallingOrSelfPermission(
Manifest.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG)
== PackageManager.PERMISSION_GRANTED;
boolean hasWritePermission =
context.checkCallingOrSelfPermission(
Manifest.permission.WRITE_DEVICE_CONFIG)
== PackageManager.PERMISSION_GRANTED;
boolean isRoot = Binder.getCallingUid() == Process.ROOT_UID;
if (isRoot || hasWritePermission) {
return;
} else if (hasAllowlistPermission) {
for (String flag : flags) {
if (!DeviceConfig.getAdbWritableFlags().contains(flag)) {
throw new SecurityException("Permission denial for flag '"
+ flag
+ "'; allowlist permission granted, but must add flag to the allowlist.");
}
}
} else {
throw new SecurityException("Permission denial to mutate flag, must have root, "
+ "WRITE_DEVICE_CONFIG, or ALLOWLISTED_WRITE_DEVICE_CONFIG");
}
}

View File

@@ -148,6 +148,8 @@
<uses-permission android:name="android.permission.LOCATION_BYPASS" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG" />
<uses-permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.MANAGE_ACCESSIBILITY" />

View File

@@ -416,7 +416,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// Shell permisssions will override permissions of our app, so add all necessary permissions
// for this test here:
InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
"android.permission.WRITE_DEVICE_CONFIG",
"android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG",
"android.permission.READ_DEVICE_CONFIG",
"android.permission.READ_CONTACTS");