Merge "Grant device ID access to app with carrier privlege on any sub ID" into qt-dev

am: 7aac1013b7

Change-Id: I78374a9cf934cc2826f322b95223de817f588a4e
This commit is contained in:
Michael Groover
2019-05-15 08:40:52 -07:00
committed by android-build-merger

View File

@@ -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;
}
// 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)) {
// If the calling package has carrier privileges for any subscription then allow access.
if (checkCarrierPrivilegeForAnySubId(context, telephonySupplier, uid)) {
return true;
}
return false;
// 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;
}
}
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();