Don't allow reading IMSI of one active sub if only has carrier privilege

on the other.

Bug: 136123413
Test: unittest
Change-Id: I67a0121d3e965f193be9e827533646423502fe70
This commit is contained in:
Malcolm Chen
2019-11-06 18:54:55 -08:00
parent 6288754ef9
commit 4bff428285
2 changed files with 50 additions and 29 deletions

View File

@@ -1589,8 +1589,8 @@ public class TelephonyManager {
* *
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
* privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
* managed profile on the device; for more details see <a * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release. * access is deprecated and will be removed in a future release.
* *
@@ -1630,8 +1630,8 @@ public class TelephonyManager {
* *
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
* privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
* managed profile on the device; for more details see <a * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release. * access is deprecated and will be removed in a future release.
* *
@@ -1690,7 +1690,8 @@ public class TelephonyManager {
* <li>The caller holds the READ_PRIVILEGED_PHONE_STATE permission.</li> * <li>The caller holds the READ_PRIVILEGED_PHONE_STATE permission.</li>
* <li>If the caller is the device or profile owner, the caller holds the * <li>If the caller is the device or profile owner, the caller holds the
* {@link Manifest.permission#READ_PHONE_STATE} permission.</li> * {@link Manifest.permission#READ_PHONE_STATE} permission.</li>
* <li>The caller has carrier privileges (see {@link #hasCarrierPrivileges()}.</li> * <li>The caller has carrier privileges (see {@link #hasCarrierPrivileges()} on any
* active subscription.</li>
* <li>The caller is the default SMS app for the device.</li> * <li>The caller is the default SMS app for the device.</li>
* </ul> * </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details * <p>The profile owner is an app that owns a managed profile on the device; for more details
@@ -1759,8 +1760,8 @@ public class TelephonyManager {
* *
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
* privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
* managed profile on the device; for more details see <a * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release. * access is deprecated and will be removed in a future release.
* *
@@ -1786,8 +1787,8 @@ public class TelephonyManager {
* *
* <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
* profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
* privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a * privileges (see {@link #hasCarrierPrivileges}) on any active subscription. The profile owner
* managed profile on the device; for more details see <a * is an app that owns a managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release. * access is deprecated and will be removed in a future release.
* *

View File

@@ -237,9 +237,10 @@ public final class TelephonyPermissions {
* <ul> * <ul>
* <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
* access check, or the calling package has carrier privileges. * access check, or the calling package has carrier privileges on any active subscription.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is * <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission. * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission
* or carrier privileges of any active subscription.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission. In this case the caller would expect to have access to the device * permission. In this case the caller would expect to have access to the device
* identifiers so false is returned instead of throwing a SecurityException to indicate * identifiers so false is returned instead of throwing a SecurityException to indicate
@@ -259,10 +260,10 @@ public final class TelephonyPermissions {
* <ul> * <ul>
* <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
* access check, or the calling package has carrier privileges. * access check, or the calling package has carrier privileges on any active subscription.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is * <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission
* or carrier privileges. * or carrier privileges of any active subscription.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission or carrier privileges. In this case the caller would expect to have access * permission or carrier privileges. In this case the caller would expect to have access
* to the device identifiers so false is returned instead of throwing a SecurityException * to the device identifiers so false is returned instead of throwing a SecurityException
@@ -271,8 +272,8 @@ public final class TelephonyPermissions {
*/ */
public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId, public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId,
String callingPackage, String message) { String callingPackage, String message) {
return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId, return checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message); context, subId, callingPackage, message, true);
} }
/** /**
@@ -282,7 +283,7 @@ public final class TelephonyPermissions {
* <ul> * <ul>
* <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
* access check, or the calling package has carrier privileges. * access check, or the calling package has carrier privileges on specified subscription.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is * <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission. * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
@@ -293,21 +294,33 @@ public final class TelephonyPermissions {
*/ */
public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId, public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
String callingPackage, String message) { String callingPackage, String message) {
return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId, return checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message); context, subId, callingPackage, message, false);
} }
/** /**
* Checks whether the app with the given pid/uid can read device identifiers. * Checks whether the app with the given pid/uid can read device identifiers.
* *
* @returns true if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the calling * <p>This method behaves in one of the following ways:
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier access * <ul>
* check. * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
* access check; or the calling package has carrier privileges on the specified
* subscription; or allowCarrierPrivilegeOnAnySub is true and has carrier privilege on
* any active subscription.
* <li>throw SecurityException: if the caller does not meet any of the requirements and is
* targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
* <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
* permission. In this case the caller would expect to have access to the device
* identifiers so false is returned instead of throwing a SecurityException to indicate
* the calling function should return dummy data.
* </ul>
*/ */
@VisibleForTesting private static boolean checkPrivilegedReadPermissionOrCarrierPrivilegePermission(
public static boolean checkReadDeviceIdentifiers(Context context, Context context, int subId, String callingPackage, String message,
Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid, boolean allowCarrierPrivilegeOnAnySub) {
String callingPackage, String message) { int uid = Binder.getCallingUid();
int pid = Binder.getCallingPid();
// Allow system and root access to the device identifiers. // Allow system and root access to the device identifiers.
final int appId = UserHandle.getAppId(uid); final int appId = UserHandle.getAppId(uid);
if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) { if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
@@ -318,10 +331,17 @@ public final class TelephonyPermissions {
uid) == PackageManager.PERMISSION_GRANTED) { uid) == PackageManager.PERMISSION_GRANTED) {
return true; return true;
} }
// If the calling package has carrier privileges for any subscription then allow access.
if (checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid)) { // If the calling package has carrier privileges for specified sub, then allow access.
if (checkCarrierPrivilegeForSubId(subId)) return true;
// If the calling package has carrier privileges for any subscription
// and allowCarrierPrivilegeOnAnySub is set true, then allow access.
if (allowCarrierPrivilegeOnAnySub && checkCarrierPrivilegeForAnySubId(
context, TELEPHONY_SUPPLIER, uid)) {
return true; return true;
} }
// if the calling package is not null then perform the DevicePolicyManager device / // if the calling package is not null then perform the DevicePolicyManager device /
// profile owner and Appop checks. // profile owner and Appop checks.
if (callingPackage != null) { if (callingPackage != null) {
@@ -347,7 +367,7 @@ public final class TelephonyPermissions {
} }
} }
return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage, return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
message); message);
} }
/** /**