From d8eb8b2690dd27d5ffe6262dd8ce8594ec8028a6 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Fri, 5 Apr 2019 18:52:08 -0700 Subject: Restricted permission mechanism - framework This change adds a mechanism for restricting permissions (only runtime for now), so that an app cannot hold the permission if it is not white listed. The whitelisting can happen at install or at any later point. There are three whitelists: system: OS managed with default grants and role holders being on it; upgrade: only OS puts on this list apps when upgrading from a pre to post restriction permission database version and OS and installer on record can remove; installer: only the installer on record can add and remove (and the system of course). Added a permission policy service that sits on top of permissions and app ops and is responsible to sync between permissions and app ops when there is an interdependecy in any direction. Added versioning to the runtime permissions database to allow operations that need to be done once on upgrade such as adding all permissions held by apps pre upgrade to the upgrade whitelist if the new permisison version inctroduces a new restricted permission. The upgrade logic is in the permission controller and we will eventually put the default grants there. NOTE: This change is reacting to a VP feedback for how we would handle SMS/CallLog restriction as we pivoted from role based approach to roles for things the user would understand plus whitelist for everything else. This would also help us roll out softly the storage permisison as there is too much churm coming from developer feedback. Exempt-From-Owner-Approval: trivial change due to APi adjustment Test: atest CtsAppSecurityHostTestCases:android.appsecurity.cts.PermissionsHostTest Test: atest CtsPermissionTestCases Test: atest CtsPermission2TestCases Test: atest RoleManagerTestCases bug:124769181 Change-Id: Ic48e3c728387ecf02f89d517ba1fe785ab9c75fd --- api/current.txt | 11 +++++++++++ api/system-current.txt | 23 ++++++++++++++--------- api/test-current.txt | 19 ++++++++++++------- 3 files changed, 37 insertions(+), 16 deletions(-) (limited to 'api') diff --git a/api/current.txt b/api/current.txt index 3fb05450c16c..d24e350e0f99 100644 --- a/api/current.txt +++ b/api/current.txt @@ -11483,10 +11483,12 @@ package android.content.pm { method public void setOriginatingUri(@Nullable android.net.Uri); method public void setReferrerUri(@Nullable android.net.Uri); method public void setSize(long); + method public void setWhitelistedRestrictedPermissions(@Nullable java.util.Set); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; field public static final int MODE_FULL_INSTALL = 1; // 0x1 field public static final int MODE_INHERIT_EXISTING = 2; // 0x2 + field @NonNull public static final java.util.Set RESTRICTED_PERMISSIONS_ALL; } public class PackageItemInfo { @@ -11523,6 +11525,7 @@ package android.content.pm { method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo); method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo); method @Deprecated public abstract void addPreferredActivity(@NonNull android.content.IntentFilter, int, @Nullable android.content.ComponentName[], @NonNull android.content.ComponentName); + method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public boolean addWhitelistedRestrictedPermission(@NonNull String, @NonNull String, int); method public abstract boolean canRequestPackageInstalls(); method public abstract String[] canonicalToCurrentPackageNames(@NonNull String[]); method @CheckResult public abstract int checkPermission(@NonNull String, @NonNull String); @@ -11592,11 +11595,13 @@ package android.content.pm { method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int); method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle); method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle); + method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) @NonNull public java.util.Set getWhitelistedRestrictedPermissions(@NonNull String, int); method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo); method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int); method public boolean hasSigningCertificate(int, @NonNull byte[], int); method public abstract boolean hasSystemFeature(@NonNull String); method public abstract boolean hasSystemFeature(@NonNull String, int); + method public boolean isDeviceUpgrading(); method public abstract boolean isInstantApp(); method public abstract boolean isInstantApp(@NonNull String); method public boolean isPackageSuspended(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; @@ -11613,6 +11618,7 @@ package android.content.pm { method @NonNull public abstract java.util.List queryPermissionsByGroup(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException; method @Deprecated public abstract void removePackageFromPreferred(@NonNull String); method public abstract void removePermission(@NonNull String); + method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public boolean removeWhitelistedRestrictedPermission(@NonNull String, @NonNull String, int); method @Nullable public abstract android.content.pm.ResolveInfo resolveActivity(@NonNull android.content.Intent, int); method @Nullable public abstract android.content.pm.ProviderInfo resolveContentProvider(@NonNull String, int); method @Nullable public abstract android.content.pm.ResolveInfo resolveService(@NonNull android.content.Intent, int); @@ -11740,6 +11746,9 @@ package android.content.pm { field public static final String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct"; field public static final String FEATURE_WIFI_PASSPOINT = "android.hardware.wifi.passpoint"; field public static final String FEATURE_WIFI_RTT = "android.hardware.wifi.rtt"; + field public static final int FLAG_PERMISSION_WHITELIST_INSTALLER = 2; // 0x2 + field public static final int FLAG_PERMISSION_WHITELIST_SYSTEM = 1; // 0x1 + field public static final int FLAG_PERMISSION_WHITELIST_UPGRADE = 4; // 0x4 field public static final int GET_ACTIVITIES = 1; // 0x1 field public static final int GET_CONFIGURATIONS = 16384; // 0x4000 field @Deprecated public static final int GET_DISABLED_COMPONENTS = 512; // 0x200 @@ -11840,7 +11849,9 @@ package android.content.pm { method @Nullable public CharSequence loadDescription(@NonNull android.content.pm.PackageManager); field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final int FLAG_COSTS_MONEY = 1; // 0x1 + field public static final int FLAG_HARD_RESTRICTED = 4; // 0x4 field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000 + field public static final int FLAG_SOFT_RESTRICTED = 8; // 0x8 field public static final int PROTECTION_DANGEROUS = 1; // 0x1 field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40 field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 diff --git a/api/system-current.txt b/api/system-current.txt index 64589093654e..eb9f82af9312 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -201,6 +201,7 @@ package android { field public static final String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES"; field public static final String USER_ACTIVITY = "android.permission.USER_ACTIVITY"; field public static final String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK"; + field public static final String WHITELIST_RESTRICTED_PERMISSIONS = "android.permission.WHITELIST_RESTRICTED_PERMISSIONS"; field public static final String WRITE_DEVICE_CONFIG = "android.permission.WRITE_DEVICE_CONFIG"; field public static final String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE"; field public static final String WRITE_EMBEDDED_SUBSCRIPTIONS = "android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"; @@ -1581,6 +1582,7 @@ package android.content.pm { method public boolean getInstallAsInstantApp(boolean); method public boolean getInstallAsVirtualPreload(); method public boolean getRequestDowngrade(); + method @NonNull public java.util.Set getWhitelistedRestrictedPermissions(); } public static class PackageInstaller.SessionParams implements android.os.Parcelable { @@ -1651,8 +1653,12 @@ package android.content.pm { field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio"; field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock"; + field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000 field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20 field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4 + field public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 2048; // 0x800 + field public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 4096; // 0x1000 + field public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 8192; // 0x2000 field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40 field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8 field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10 @@ -1708,6 +1714,7 @@ package android.content.pm { field public static final int MATCH_ANY_USER = 4194304; // 0x400000 field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000 field public static final int MATCH_INSTANT = 8388608; // 0x800000 + field public static boolean RESTRICTED_PERMISSIONS_ENABLED; field public static final int RESTRICTION_HIDE_FROM_SUGGESTIONS = 1; // 0x1 field public static final int RESTRICTION_HIDE_NOTIFICATIONS = 2; // 0x2 field public static final int RESTRICTION_NONE = 0; // 0x0 @@ -1722,7 +1729,7 @@ package android.content.pm { method public void onPermissionsChanged(int); } - @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags { + @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags { } public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable { @@ -5451,7 +5458,7 @@ package android.os { } public static interface RemoteCallback.OnResultListener { - method public void onResult(android.os.Bundle); + method public void onResult(@Nullable android.os.Bundle); } public class ServiceSpecificException extends java.lang.RuntimeException { @@ -5694,6 +5701,7 @@ package android.permission { method @NonNull public abstract java.util.List onGetAppPermissions(@NonNull String); method @NonNull public abstract java.util.List onGetPermissionUsages(boolean, long); method public abstract void onGetRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.OutputStream); + method public abstract void onGrantOrUpgradeDefaultRuntimePermissions(); method @BinderThread public abstract boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String, @NonNull android.os.UserHandle); method @BinderThread public abstract void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream); method public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String); @@ -5703,7 +5711,9 @@ package android.permission { } public final class PermissionManager { + method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public int getRuntimePermissionsVersion(); method @NonNull public java.util.List getSplitPermissions(); + method @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public void setRuntimePermissionsVersion(@IntRange(from=0) int); } public static final class PermissionManager.SplitPermissionInfo { @@ -5871,6 +5881,7 @@ package android.provider { field public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention"; field public static final String NAMESPACE_MEDIA_NATIVE = "media_native"; field public static final String NAMESPACE_NETD_NATIVE = "netd_native"; + field public static final String NAMESPACE_PRIVACY = "privacy"; field public static final String NAMESPACE_ROLLBACK = "rollback"; field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot"; field public static final String NAMESPACE_RUNTIME = "runtime"; @@ -5891,12 +5902,6 @@ package android.provider { method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String); } - public static interface DeviceConfig.Privacy { - field public static final String NAMESPACE = "privacy"; - field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled"; - field public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled"; - } - public static class DeviceConfig.Properties { method public boolean getBoolean(@NonNull String, boolean); method public float getFloat(@NonNull String, float); @@ -6075,7 +6080,6 @@ package android.provider { field public static final String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis"; field public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update"; field public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt"; - field public static final String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled"; field public static final String THEATER_MODE_ON = "theater_mode_on"; field public static final String WEBVIEW_MULTIPROCESS = "webview_multiprocess"; field public static final String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds"; @@ -9521,6 +9525,7 @@ package android.util { field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_GRANTED = 5; // 0x5 field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED = 1; // 0x1 field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED = 3; // 0x3 + field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_RESTRICTED_PERMISSION = 9; // 0x9 field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED = 2; // 0x2 field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED = 6; // 0x6 field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE = 7; // 0x7 diff --git a/api/test-current.txt b/api/test-current.txt index 99cdfb012155..973e70067c37 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -655,8 +655,13 @@ package android.content.pm { ctor public LauncherApps(android.content.Context); } + public static class PackageInstaller.SessionInfo implements android.os.Parcelable { + method @NonNull public java.util.Set getWhitelistedRestrictedPermissions(); + } + public static class PackageInstaller.SessionParams implements android.os.Parcelable { method public void setEnableRollback(boolean); + method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex(); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged(); } @@ -679,7 +684,11 @@ package android.content.pm { method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle); field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage"; field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption"; + field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000 field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4 + field public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 2048; // 0x800 + field public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 4096; // 0x1000 + field public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 8192; // 0x2000 field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40 field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8 field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80 @@ -688,6 +697,7 @@ package android.content.pm { field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1 field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000 field public static final int MATCH_KNOWN_PACKAGES = 4202496; // 0x402000 + field public static boolean RESTRICTED_PERMISSIONS_ENABLED; field public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services"; field public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared"; } @@ -1820,7 +1830,7 @@ package android.os { } public static interface RemoteCallback.OnResultListener { - method public void onResult(android.os.Bundle); + method public void onResult(@Nullable android.os.Bundle); } public final class StrictMode { @@ -2101,6 +2111,7 @@ package android.provider { method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean); field public static final String NAMESPACE_AUTOFILL = "autofill"; field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; + field public static final String NAMESPACE_PRIVACY = "privacy"; field public static final String NAMESPACE_ROLLBACK = "rollback"; field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot"; } @@ -2113,11 +2124,6 @@ package android.provider { method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String); } - public static interface DeviceConfig.Privacy { - field public static final String NAMESPACE = "privacy"; - field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled"; - } - public static class DeviceConfig.Properties { method public boolean getBoolean(@NonNull String, boolean); method public float getFloat(@NonNull String, float); @@ -2172,7 +2178,6 @@ package android.provider { field public static final String LOW_POWER_MODE = "low_power"; field public static final String LOW_POWER_MODE_STICKY = "low_power_sticky"; field public static final String OVERLAY_DISPLAY_DEVICES = "overlay_display_devices"; - field public static final String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled"; field public static final String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package"; } -- cgit v1.2.3-59-g8ed1b