summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyPermissions.java146
1 files changed, 70 insertions, 76 deletions
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 64c1830c5e5c..2552f045eedf 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -209,18 +209,9 @@ public final class TelephonyPermissions {
context.enforcePermission(
android.Manifest.permission.READ_PHONE_STATE, pid, uid, message);
} catch (SecurityException phoneStateException) {
- SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
- Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- int[] activeSubIds = sm.getActiveSubscriptionIdList();
- for (int activeSubId : activeSubIds) {
- // If we don't have the runtime permission, but do have carrier privileges, that
- // suffices for reading phone state.
- if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid)
- == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
- return true;
- }
- }
- return false;
+ // If we don't have the runtime permission, but do have carrier privileges, that
+ // suffices for reading phone state.
+ return checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid);
}
}
@@ -236,9 +227,9 @@ public final class TelephonyPermissions {
*
* <p>This method behaves in one of the following ways:
* <ul>
- * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the
- * calling package passes a DevicePolicyManager Device Owner / Profile Owner device
- * identifier access 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.
* <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
@@ -258,9 +249,9 @@ public final class TelephonyPermissions {
*
* <p>This method behaves in one of the following ways:
* <ul>
- * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the
- * calling package passes a DevicePolicyManager Device Owner / Profile Owner device
- * identifier access 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.
* <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
* or carrier privileges.
@@ -272,23 +263,8 @@ public final class TelephonyPermissions {
*/
public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId,
String callingPackage, String message) {
- int pid = Binder.getCallingPid();
- int uid = Binder.getCallingUid();
- // if the device identifier check completes successfully then grant access.
- if (checkReadDeviceIdentifiers(context, pid, uid, callingPackage)) {
- return true;
- }
- // Calling packages with carrier privileges will also have access to device identifiers, but
- // this may be removed in a future release.
- if (checkCarrierPrivilegeForSubId(subId)) {
- return true;
- }
- // else the calling package is not authorized to access the device identifiers; call
- // a central method to report the failure based on the target SDK and if the calling package
- // has the READ_PHONE_STATE permission or carrier privileges that were previously required
- // to access the identifiers.
- return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
- message);
+ return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId,
+ Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message);
}
/**
@@ -298,7 +274,7 @@ public final class TelephonyPermissions {
* <ul>
* <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 privleges.
+ * access check, or the calling package has carrier privileges.
* <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
@@ -309,19 +285,8 @@ public final class TelephonyPermissions {
*/
public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
String callingPackage, String message) {
- int pid = Binder.getCallingPid();
- int uid = Binder.getCallingUid();
- // if the device identifiers can be read then grant access to the subscriber identifiers
- if (checkReadDeviceIdentifiers(context, pid, uid, callingPackage)) {
- return true;
- }
- // If the calling package has carrier privileges then allow access to the subscriber
- // identifiers.
- if (checkCarrierPrivilegeForSubId(subId)) {
- return true;
- }
- return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
- message);
+ return checkReadDeviceIdentifiers(context, TELEPHONY_SUPPLIER, subId,
+ Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, message);
}
/**
@@ -331,8 +296,10 @@ public final class TelephonyPermissions {
* package passes a DevicePolicyManager Device Owner / Profile Owner device identifier access
* check.
*/
- private static boolean checkReadDeviceIdentifiers(Context context, int pid, int uid,
- String callingPackage) {
+ @VisibleForTesting
+ public static boolean checkReadDeviceIdentifiers(Context context,
+ Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
+ String callingPackage, String message) {
// Allow system and root access to the device identifiers.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
@@ -343,31 +310,36 @@ public final class TelephonyPermissions {
uid) == PackageManager.PERMISSION_GRANTED) {
return true;
}
- // if the calling package is null then return now as there's no way to perform the
- // DevicePolicyManager device / profile owner and AppOp checks
- if (callingPackage == null) {
- return false;
+ // If the calling package has carrier privileges for any subscription then allow access.
+ if (checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid)) {
+ return true;
}
- // Allow access to an app that has been granted the READ_DEVICE_IDENTIFIERS app op.
- long token = Binder.clearCallingIdentity();
- AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(
- Context.APP_OPS_SERVICE);
- try {
- if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
- callingPackage) == AppOpsManager.MODE_ALLOWED) {
+ // if the calling package is not null then perform the DevicePolicyManager device /
+ // profile owner and Appop checks.
+ if (callingPackage != null) {
+ // Allow access to an app that has been granted the READ_DEVICE_IDENTIFIERS app op.
+ long token = Binder.clearCallingIdentity();
+ AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(
+ Context.APP_OPS_SERVICE);
+ try {
+ if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
+ callingPackage) == AppOpsManager.MODE_ALLOWED) {
+ return true;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ // Allow access to a device / profile owner app.
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) context.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccess(
+ callingPackage, pid, uid)) {
return true;
}
- } finally {
- Binder.restoreCallingIdentity(token);
}
- // Allow access to a device / profile owner app.
- DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccess(
- callingPackage, pid, uid)) {
- return true;
- }
- return false;
+ return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
+ message);
}
/**
@@ -403,10 +375,12 @@ public final class TelephonyPermissions {
try {
callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser(
callingPackage, 0, UserHandle.getUserId(uid));
- if (callingPackageInfo.isSystemApp()) {
- isPreinstalled = true;
- if (callingPackageInfo.isPrivilegedApp()) {
- isPrivApp = true;
+ if (callingPackageInfo != null) {
+ if (callingPackageInfo.isSystemApp()) {
+ isPreinstalled = true;
+ if (callingPackageInfo.isPrivilegedApp()) {
+ isPrivApp = true;
+ }
}
}
} catch (PackageManager.NameNotFoundException e) {
@@ -651,6 +625,26 @@ public final class TelephonyPermissions {
}
}
+ /**
+ * Returns whether the provided uid has carrier privileges for any active subscription ID.
+ */
+ private static boolean checkCarrierPrivilegeForAnySubId(Context context,
+ Supplier<ITelephony> telephonySupplier, int uid) {
+ SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ int[] activeSubIds = sm.getActiveSubscriptionIdList();
+ if (activeSubIds != null) {
+ for (int activeSubId : activeSubIds) {
+ if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
private static int getCarrierPrivilegeStatus(
Supplier<ITelephony> telephonySupplier, int subId, int uid) {
ITelephony telephony = telephonySupplier.get();