From 596437fd4e0941df378558a374c172148bb37b7c Mon Sep 17 00:00:00 2001 From: Stanislav Zholnin Date: Fri, 28 Dec 2018 15:34:23 +0000 Subject: [PATCH] Added a new set of permissions for DeviceConfig API. Permissions READ_DEVICE_CONFIG and WRITE_DEVICE_CONFIG are required to use DeviceConfig API. Actual checks for new permissions are not added as we are waiting for gmscore to include them into manifest. Also added "configurator" protection flag. Test: atest FrameworksCoreTests:DeviceConfigTest atest FrameworksCoreTests:SettingsProviderTest atest SettingsProviderTest:DeviceConfigServiceTest Bug:109919982 Bug:113100523 Bug:113101834 Bug:117663715 Change-Id: I66c256b57c5491201c6c7834620a287b6c81c23c --- api/system-current.txt | 3 +++ api/test-current.txt | 1 + .../android/content/pm/PackageManagerInternal.java | 2 ++ core/java/android/content/pm/PermissionInfo.java | 14 ++++++++++++++ core/java/android/provider/DeviceConfig.java | 9 +++++++++ core/java/android/provider/Settings.java | 7 +++---- core/res/AndroidManifest.xml | 10 ++++++++++ core/res/res/values/attrs_manifest.xml | 3 +++ core/res/res/values/config.xml | 3 +++ core/res/res/values/symbols.xml | 1 + core/tests/coretests/AndroidManifest.xml | 2 ++ .../providers/settings/SettingsProvider.java | 7 ++++--- packages/SettingsProvider/test/AndroidManifest.xml | 2 ++ .../android/server/pm/PackageManagerService.java | 5 +++++ .../server/pm/permission/BasePermission.java | 4 ++++ .../pm/permission/PermissionManagerService.java | 7 +++++++ 16 files changed, 73 insertions(+), 7 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index ef3455d544fda..a22e7ef875f60 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -127,6 +127,7 @@ package android { field public static final java.lang.String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES"; field public static final java.lang.String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS"; field public static final java.lang.String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS"; + field public static final java.lang.String READ_DEVICE_CONFIG = "android.permission.READ_DEVICE_CONFIG"; field public static final java.lang.String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE"; field public static final java.lang.String READ_INSTALL_SESSIONS = "android.permission.READ_INSTALL_SESSIONS"; field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY"; @@ -182,6 +183,7 @@ package android { field public static final java.lang.String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES"; field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY"; field public static final java.lang.String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK"; + field public static final java.lang.String WRITE_DEVICE_CONFIG = "android.permission.WRITE_DEVICE_CONFIG"; field public static final java.lang.String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE"; field public static final java.lang.String WRITE_EMBEDDED_SUBSCRIPTIONS = "android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"; field public static final java.lang.String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE"; @@ -1347,6 +1349,7 @@ package android.content.pm { public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { field public static final int FLAG_REMOVED = 2; // 0x2 + field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000 field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 diff --git a/api/test-current.txt b/api/test-current.txt index 8ea7f20109f32..4518e65a45a29 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -374,6 +374,7 @@ package android.content.pm { } public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { + field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000 field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000 diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 83979e925be1c..822c54e624de2 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -55,6 +55,7 @@ public abstract class PackageManagerInternal { public static final int PACKAGE_PERMISSION_CONTROLLER = 6; public static final int PACKAGE_WELLBEING = 7; public static final int PACKAGE_DOCUMENTER = 8; + public static final int PACKAGE_CONFIGURATOR = 9; @IntDef(value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, @@ -65,6 +66,7 @@ public abstract class PackageManagerInternal { PACKAGE_PERMISSION_CONTROLLER, PACKAGE_WELLBEING, PACKAGE_DOCUMENTER, + PACKAGE_CONFIGURATOR, }) @Retention(RetentionPolicy.SOURCE) public @interface KnownPackage {} diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index bb8c92dba71aa..9fe9ed0aefb44 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -202,6 +202,16 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @TestApi public static final int PROTECTION_FLAG_DOCUMENTER = 0x40000; + /** + * Additional flag for {@link #protectionLevel}, corresponding to the + * {@code configurator} value of {@link android.R.attr#protectionLevel}. + * + * @hide + */ + @SystemApi + @TestApi + public static final int PROTECTION_FLAG_CONFIGURATOR = 0x80000; + /** @hide */ @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { @@ -221,6 +231,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER, PROTECTION_FLAG_WELLBEING, PROTECTION_FLAG_DOCUMENTER, + PROTECTION_FLAG_CONFIGURATOR, }) @Retention(RetentionPolicy.SOURCE) public @interface ProtectionFlags {} @@ -416,6 +427,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0) { protLevel += "|documenter"; } + if ((level & PROTECTION_FLAG_CONFIGURATOR) != 0) { + protLevel += "|configurator"; + } return protLevel; } diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 4e207ed6556e9..205c667917798 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -16,9 +16,13 @@ package android.provider; +import static android.Manifest.permission.READ_DEVICE_CONFIG; +import static android.Manifest.permission.WRITE_DEVICE_CONFIG; + import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.app.ActivityThread; import android.content.ContentResolver; @@ -69,6 +73,7 @@ public final class DeviceConfig { * @hide */ @SystemApi + @RequiresPermission(READ_DEVICE_CONFIG) public static String getProperty(String namespace, String name) { ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver(); String compositeName = createCompositeName(namespace, name); @@ -96,6 +101,7 @@ public final class DeviceConfig { * @hide */ @SystemApi + @RequiresPermission(WRITE_DEVICE_CONFIG) public static boolean setProperty( String namespace, String name, String value, boolean makeDefault) { ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver(); @@ -116,6 +122,7 @@ public final class DeviceConfig { * @hide */ @SystemApi + @RequiresPermission(WRITE_DEVICE_CONFIG) public static void resetToDefaults(@ResetMode int resetMode, @Nullable String namespace) { ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver(); Settings.Config.resetToDefaults(contentResolver, resetMode, namespace); @@ -137,10 +144,12 @@ public final class DeviceConfig { * @hide */ @SystemApi + @RequiresPermission(READ_DEVICE_CONFIG) public static void addOnPropertyChangedListener( @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertyChangedListener onPropertyChangedListener) { + // TODO enforce READ_DEVICE_CONFIG permission synchronized (sLock) { Pair oldNamespace = sListeners.get(onPropertyChangedListener); if (oldNamespace == null) { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 5bb5ee8803985..51c1e701071f1 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -14041,7 +14041,7 @@ public final class Settings { * * @hide */ - // TODO(b/117663715): require a new read permission + @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) static String getString(ContentResolver resolver, String name) { return sNameValueCache.getStringForUser(resolver, name, resolver.getUserId()); } @@ -14064,8 +14064,7 @@ public final class Settings { * * @hide */ - // TODO(b/117663715): require a new write permission restricted to a single source - @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + @RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG) static boolean putString(@NonNull ContentResolver resolver, @NonNull String name, @Nullable String value, boolean makeDefault) { return sNameValueCache.putStringForUser(resolver, name, value, null, makeDefault, @@ -14087,7 +14086,7 @@ public final class Settings { * @hide */ // TODO(b/117663715): require a new write permission restricted to a single source - @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + @RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG) static void resetToDefaults(@NonNull ContentResolver resolver, @ResetMode int resetMode, @Nullable String prefix) { try { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 449a7b3305ad5..b6fab565a3706 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2526,6 +2526,16 @@ + + + + + + diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 54f6c632907f1..613e091a0956f 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -274,6 +274,9 @@ + + diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 1c98c66b1f483..0e496b73255ce 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2761,6 +2761,9 @@ + + + true diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 01fbf80f4e630..311748cff9e39 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2139,6 +2139,7 @@ + diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 46d4a4773389c..3afa53230d214 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -56,6 +56,7 @@ + @@ -65,6 +66,7 @@ + diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index bce559396dddb..5153f9ea86d16 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -1052,7 +1052,7 @@ public class SettingsProvider extends ContentProvider { } // TODO(b/117663715): Ensure the caller can access the setting. - // enforceSettingReadable(name, SETTINGS_TYPE_CONFIG, UserHandle.getCallingUserId()); + // enforceReadPermission(READ_DEVICE_CONFIG); // Get the value. synchronized (mLock) { @@ -1088,8 +1088,9 @@ public class SettingsProvider extends ContentProvider { private boolean mutateConfigSetting(String name, String value, String prefix, boolean makeDefault, int operation, int mode) { - // TODO(b/117663715): check the new permission when it's added. - // enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); + + // TODO(b/117663715): Ensure the caller can access the setting. + // enforceReadPermission(WRITE_DEVICE_CONFIG); // Perform the mutation. synchronized (mLock) { diff --git a/packages/SettingsProvider/test/AndroidManifest.xml b/packages/SettingsProvider/test/AndroidManifest.xml index 87a4f603f70bc..ebdf9b1a2791a 100644 --- a/packages/SettingsProvider/test/AndroidManifest.xml +++ b/packages/SettingsProvider/test/AndroidManifest.xml @@ -20,6 +20,8 @@ + + diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 522ab0bf93e2f..a99b317ad114f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1338,6 +1338,7 @@ public class PackageManagerService extends IPackageManager.Stub final @Nullable String mSystemTextClassifierPackage; final @Nullable String mWellbeingPackage; final @Nullable String mDocumenterPackage; + final @Nullable String mConfiguratorPackage; final @NonNull String mServicesSystemSharedLibraryPackageName; final @NonNull String mSharedSystemSharedLibraryPackageName; @@ -2861,6 +2862,8 @@ public class PackageManagerService extends IPackageManager.Stub mWellbeingPackage = getWellbeingPackageName(); mDocumenterPackage = getDocumenterPackageName(); + mConfiguratorPackage = + mContext.getString(R.string.config_deviceConfiguratorPackageName); // Now that we know all of the shared libraries, update all clients to have // the correct library paths. @@ -23109,6 +23112,8 @@ public class PackageManagerService extends IPackageManager.Stub return mWellbeingPackage; case PackageManagerInternal.PACKAGE_DOCUMENTER: return mDocumenterPackage; + case PackageManagerInternal.PACKAGE_CONFIGURATOR: + return mConfiguratorPackage; } return null; } diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 3a49412357d8f..17f83479a3b13 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -247,6 +247,10 @@ public final class BasePermission { public boolean isDocumenter() { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_DOCUMENTER) != 0; } + public boolean isConfigurator() { + return (protectionLevel & PermissionInfo.PROTECTION_FLAG_CONFIGURATOR) + != 0; + } public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) { if (!origPackageName.equals(sourcePackageName)) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 93964cb09ae63..30b5e49bc3fd2 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1640,6 +1640,13 @@ public class PermissionManagerService { // Special permissions for the system default text classifier. allowed = true; } + if (!allowed && bp.isConfigurator() + && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( + PackageManagerInternal.PACKAGE_CONFIGURATOR, + UserHandle.USER_SYSTEM))) { + // Special permissions for the device configurator. + allowed = true; + } if (!allowed && bp.isWellbeing() && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {