Loading core/java/android/provider/Settings.java +22 −0 Original line number Original line Diff line number Diff line Loading @@ -12380,6 +12380,28 @@ public final class Settings { public static final String SMS_ACCESS_RESTRICTION_ENABLED = public static final String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled"; "sms_access_restriction_enabled"; /** * If set to 1, an app must have the READ_PRIVILEGED_PHONE_STATE permission (or be a device * / profile owner with the READ_PHONE_STATE permission) to access device identifiers. * * STOPSHIP: Remove this once we ship with the new device identifier check enabled. * * @hide */ public static final String PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED = "privileged_device_identifier_check_enabled"; /** * If set to 1, an app that is targeting Q and does not meet the new requirements to access * device identifiers will receive a SecurityException. * * STOPSHIP: Remove this once we ship with the new device identifier check enabled. * * @hide */ public static final String PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED = "privileged_device_identifier_target_q_behavior_enabled"; /** /** * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored * and restoring to lower version of platform API will be skipped. * and restoring to lower version of platform API will be skipped. Loading core/tests/coretests/src/android/provider/SettingsBackupTest.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -368,6 +368,8 @@ public class SettingsBackupTest { Settings.Global.PRIV_APP_OOB_ENABLED, Settings.Global.PRIV_APP_OOB_ENABLED, Settings.Global.PRIV_APP_OOB_LIST, Settings.Global.PRIV_APP_OOB_LIST, Settings.Global.PRIVATE_DNS_DEFAULT_MODE, Settings.Global.PRIVATE_DNS_DEFAULT_MODE, Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED, Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED, Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS, Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS, Settings.Global.RADIO_BLUETOOTH, Settings.Global.RADIO_BLUETOOTH, Settings.Global.RADIO_CELL, Settings.Global.RADIO_CELL, Loading telephony/java/com/android/internal/telephony/TelephonyPermissions.java +20 −17 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.telephony.Rlog; import android.telephony.Rlog; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; Loading @@ -44,10 +45,6 @@ public final class TelephonyPermissions { private static final boolean DBG = false; private static final boolean DBG = false; // When set to true this flag will treat all apps that fail the device identifier check as // though they are targeting pre-Q and return dummy data instead of throwing a SecurityException private static final boolean RELAX_DEVICE_IDENTIFIER_CHECK = true; private static final Supplier<ITelephony> TELEPHONY_SUPPLIER = () -> private static final Supplier<ITelephony> TELEPHONY_SUPPLIER = () -> ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); Loading Loading @@ -280,23 +277,29 @@ public final class TelephonyPermissions { */ */ private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid, private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid, int uid, String callingPackage, String message) { int uid, String callingPackage, String message) { // if the device identifier check is relaxed then just return false to return dummy data to // the caller instead of throwing a SecurityException for apps targeting Q+. if (RELAX_DEVICE_IDENTIFIER_CHECK) { Log.wtf(LOG_TAG, Log.wtf(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message); "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message); return false; // if the device identifier check is relaxed then revert to the READ_PHONE_STATE permission // check that was previously required to access device identifiers. boolean relaxDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(), Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED, 0) == 0; if (relaxDeviceIdentifierCheck) { return checkReadPhoneState(context, subId, pid, uid, callingPackage, message); } else { } else { boolean targetQBehaviorDisabled = Settings.Global.getInt(context.getContentResolver(), Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED, 0) == 0; if (callingPackage != null) { if (callingPackage != null) { try { try { // if the target SDK is pre-Q then check if the calling package would have // if the target SDK is pre-Q or the target Q behavior is disabled then check if // previously had access to device identifiers. // the calling package would have previously had access to device identifiers. ApplicationInfo callingPackageInfo = ApplicationInfo callingPackageInfo = context.getPackageManager().getApplicationInfo( context.getPackageManager().getApplicationInfo( callingPackage, 0); callingPackage, 0); if (callingPackageInfo != null if (callingPackageInfo != null && ( && callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q) { callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q if (context.checkPermission(android.Manifest.permission.READ_PHONE_STATE, || targetQBehaviorDisabled)) { if (context.checkPermission( android.Manifest.permission.READ_PHONE_STATE, pid, pid, uid) == PackageManager.PERMISSION_GRANTED) { uid) == PackageManager.PERMISSION_GRANTED) { return false; return false; Loading @@ -312,8 +315,8 @@ public final class TelephonyPermissions { // default to throwing the SecurityException. // default to throwing the SecurityException. } } } } throw new SecurityException(message + ": The user " + uid + " does not have the " throw new SecurityException(message + ": The user " + uid + "READ_PRIVILEGED_PHONE_STATE permission to access the device identifiers"); + " does not meet the requirements to access device identifiers."); } } } } Loading Loading
core/java/android/provider/Settings.java +22 −0 Original line number Original line Diff line number Diff line Loading @@ -12380,6 +12380,28 @@ public final class Settings { public static final String SMS_ACCESS_RESTRICTION_ENABLED = public static final String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled"; "sms_access_restriction_enabled"; /** * If set to 1, an app must have the READ_PRIVILEGED_PHONE_STATE permission (or be a device * / profile owner with the READ_PHONE_STATE permission) to access device identifiers. * * STOPSHIP: Remove this once we ship with the new device identifier check enabled. * * @hide */ public static final String PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED = "privileged_device_identifier_check_enabled"; /** * If set to 1, an app that is targeting Q and does not meet the new requirements to access * device identifiers will receive a SecurityException. * * STOPSHIP: Remove this once we ship with the new device identifier check enabled. * * @hide */ public static final String PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED = "privileged_device_identifier_target_q_behavior_enabled"; /** /** * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored * and restoring to lower version of platform API will be skipped. * and restoring to lower version of platform API will be skipped. Loading
core/tests/coretests/src/android/provider/SettingsBackupTest.java +2 −0 Original line number Original line Diff line number Diff line Loading @@ -368,6 +368,8 @@ public class SettingsBackupTest { Settings.Global.PRIV_APP_OOB_ENABLED, Settings.Global.PRIV_APP_OOB_ENABLED, Settings.Global.PRIV_APP_OOB_LIST, Settings.Global.PRIV_APP_OOB_LIST, Settings.Global.PRIVATE_DNS_DEFAULT_MODE, Settings.Global.PRIVATE_DNS_DEFAULT_MODE, Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED, Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED, Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS, Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS, Settings.Global.RADIO_BLUETOOTH, Settings.Global.RADIO_BLUETOOTH, Settings.Global.RADIO_CELL, Settings.Global.RADIO_CELL, Loading
telephony/java/com/android/internal/telephony/TelephonyPermissions.java +20 −17 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.telephony.Rlog; import android.telephony.Rlog; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; Loading @@ -44,10 +45,6 @@ public final class TelephonyPermissions { private static final boolean DBG = false; private static final boolean DBG = false; // When set to true this flag will treat all apps that fail the device identifier check as // though they are targeting pre-Q and return dummy data instead of throwing a SecurityException private static final boolean RELAX_DEVICE_IDENTIFIER_CHECK = true; private static final Supplier<ITelephony> TELEPHONY_SUPPLIER = () -> private static final Supplier<ITelephony> TELEPHONY_SUPPLIER = () -> ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); Loading Loading @@ -280,23 +277,29 @@ public final class TelephonyPermissions { */ */ private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid, private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid, int uid, String callingPackage, String message) { int uid, String callingPackage, String message) { // if the device identifier check is relaxed then just return false to return dummy data to // the caller instead of throwing a SecurityException for apps targeting Q+. if (RELAX_DEVICE_IDENTIFIER_CHECK) { Log.wtf(LOG_TAG, Log.wtf(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message); "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message); return false; // if the device identifier check is relaxed then revert to the READ_PHONE_STATE permission // check that was previously required to access device identifiers. boolean relaxDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(), Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED, 0) == 0; if (relaxDeviceIdentifierCheck) { return checkReadPhoneState(context, subId, pid, uid, callingPackage, message); } else { } else { boolean targetQBehaviorDisabled = Settings.Global.getInt(context.getContentResolver(), Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED, 0) == 0; if (callingPackage != null) { if (callingPackage != null) { try { try { // if the target SDK is pre-Q then check if the calling package would have // if the target SDK is pre-Q or the target Q behavior is disabled then check if // previously had access to device identifiers. // the calling package would have previously had access to device identifiers. ApplicationInfo callingPackageInfo = ApplicationInfo callingPackageInfo = context.getPackageManager().getApplicationInfo( context.getPackageManager().getApplicationInfo( callingPackage, 0); callingPackage, 0); if (callingPackageInfo != null if (callingPackageInfo != null && ( && callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q) { callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q if (context.checkPermission(android.Manifest.permission.READ_PHONE_STATE, || targetQBehaviorDisabled)) { if (context.checkPermission( android.Manifest.permission.READ_PHONE_STATE, pid, pid, uid) == PackageManager.PERMISSION_GRANTED) { uid) == PackageManager.PERMISSION_GRANTED) { return false; return false; Loading @@ -312,8 +315,8 @@ public final class TelephonyPermissions { // default to throwing the SecurityException. // default to throwing the SecurityException. } } } } throw new SecurityException(message + ": The user " + uid + " does not have the " throw new SecurityException(message + ": The user " + uid + "READ_PRIVILEGED_PHONE_STATE permission to access the device identifiers"); + " does not meet the requirements to access device identifiers."); } } } } Loading