1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.internal.telephony; 17 18 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 19 20 import android.Manifest; 21 import android.annotation.Nullable; 22 import android.app.AppOpsManager; 23 import android.content.Context; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.PackageManager; 26 import android.os.Binder; 27 import android.os.Build; 28 import android.os.Process; 29 import android.os.UserHandle; 30 import android.permission.LegacyPermissionManager; 31 import android.telephony.SubscriptionManager; 32 import android.telephony.TelephonyManager; 33 import android.util.Log; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 37 import java.util.HashMap; 38 import java.util.HashSet; 39 import java.util.Map; 40 import java.util.Set; 41 42 /** Utility class for Telephony permission enforcement. */ 43 public final class TelephonyPermissions { 44 private static final String LOG_TAG = "TelephonyPermissions"; 45 46 private static final boolean DBG = false; 47 48 /** 49 * Whether to disable the new device identifier access restrictions. 50 */ 51 private static final String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED = 52 "device_identifier_access_restrictions_disabled"; 53 54 // Contains a mapping of packages that did not meet the new requirements to access device 55 // identifiers and the methods they were attempting to invoke; used to prevent duplicate 56 // reporting of packages / methods. 57 private static final Map<String, Set<String>> sReportedDeviceIDPackages; 58 static { 59 sReportedDeviceIDPackages = new HashMap<>(); 60 } 61 TelephonyPermissions()62 private TelephonyPermissions() {} 63 64 /** 65 * Check whether the caller (or self, if not processing an IPC) can read phone state. 66 * 67 * <p>This method behaves in one of the following ways: 68 * <ul> 69 * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the 70 * READ_PHONE_STATE runtime permission, or carrier privileges on the given subId. 71 * <li>throw SecurityException: if the caller didn't declare any of these permissions, or, for 72 * apps which support runtime permissions, if the caller does not currently have any of 73 * these permissions. 74 * <li>return false: if the caller lacks all of these permissions and doesn't support runtime 75 * permissions. This implies that the user revoked the ability to read phone state 76 * manually (via AppOps). In this case we can't throw as it would break app compatibility, 77 * so we return false to indicate that the calling function should return placeholder 78 * data. 79 * </ul> 80 * 81 * <p>Note: for simplicity, this method always returns false for callers using legacy 82 * permissions and who have had READ_PHONE_STATE revoked, even if they are carrier-privileged. 83 * Such apps should migrate to runtime permissions or stop requiring READ_PHONE_STATE on P+ 84 * devices. 85 * 86 * @param subId the subId of the relevant subscription; used to check carrier privileges. May be 87 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} to skip this check for cases 88 * where it isn't relevant (hidden APIs, or APIs which are otherwise okay to leave 89 * inaccesible to carrier-privileged apps). 90 */ checkCallingOrSelfReadPhoneState( Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message)91 public static boolean checkCallingOrSelfReadPhoneState( 92 Context context, int subId, String callingPackage, @Nullable String callingFeatureId, 93 String message) { 94 return checkReadPhoneState(context, subId, Binder.getCallingPid(), Binder.getCallingUid(), 95 callingPackage, callingFeatureId, message); 96 } 97 98 /** Identical to checkCallingOrSelfReadPhoneState but never throws SecurityException */ checkCallingOrSelfReadPhoneStateNoThrow( Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message)99 public static boolean checkCallingOrSelfReadPhoneStateNoThrow( 100 Context context, int subId, String callingPackage, @Nullable String callingFeatureId, 101 String message) { 102 try { 103 return checkCallingOrSelfReadPhoneState(context, subId, callingPackage, 104 callingFeatureId, message); 105 } catch (SecurityException se) { 106 return false; 107 } 108 } 109 110 /** 111 * Check whether the app with the given pid/uid can read phone state. 112 * 113 * <p>This method behaves in one of the following ways: 114 * <ul> 115 * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the 116 * READ_PHONE_STATE runtime permission, or carrier privileges on the given subId. 117 * <li>throw SecurityException: if the caller didn't declare any of these permissions, or, for 118 * apps which support runtime permissions, if the caller does not currently have any of 119 * these permissions. 120 * <li>return false: if the caller lacks all of these permissions and doesn't support runtime 121 * permissions. This implies that the user revoked the ability to read phone state 122 * manually (via AppOps). In this case we can't throw as it would break app compatibility, 123 * so we return false to indicate that the calling function should return placeholder 124 * data. 125 * </ul> 126 * 127 * <p>Note: for simplicity, this method always returns false for callers using legacy 128 * permissions and who have had READ_PHONE_STATE revoked, even if they are carrier-privileged. 129 * Such apps should migrate to runtime permissions or stop requiring READ_PHONE_STATE on P+ 130 * devices. 131 */ checkReadPhoneState( Context context, int subId, int pid, int uid, String callingPackage, @Nullable String callingFeatureId, String message)132 public static boolean checkReadPhoneState( 133 Context context, int subId, int pid, int uid, String callingPackage, 134 @Nullable String callingFeatureId, String message) { 135 try { 136 context.enforcePermission( 137 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message); 138 139 // SKIP checking for run-time permission since caller has PRIVILEGED permission 140 return true; 141 } catch (SecurityException privilegedPhoneStateException) { 142 try { 143 context.enforcePermission( 144 android.Manifest.permission.READ_PHONE_STATE, pid, uid, message); 145 } catch (SecurityException phoneStateException) { 146 // If we don't have the runtime permission, but do have carrier privileges, that 147 // suffices for reading phone state. 148 if (SubscriptionManager.isValidSubscriptionId(subId)) { 149 enforceCarrierPrivilege(context, subId, uid, message); 150 return true; 151 } 152 throw phoneStateException; 153 } 154 } 155 156 // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been 157 // revoked. 158 AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 159 return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage, 160 callingFeatureId, null) == AppOpsManager.MODE_ALLOWED; 161 } 162 163 /** 164 * Check whether the calling packages has carrier privileges for the passing subscription. 165 * @return {@code true} if the caller has carrier privileges, {@false} otherwise. 166 */ checkCarrierPrivilegeForSubId(Context context, int subId)167 public static boolean checkCarrierPrivilegeForSubId(Context context, int subId) { 168 if (SubscriptionManager.isValidSubscriptionId(subId) 169 && getCarrierPrivilegeStatus(context, subId, Binder.getCallingUid()) 170 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 171 return true; 172 } 173 return false; 174 } 175 176 /** 177 * Check whether the app with the given pid/uid can read phone state, or has carrier 178 * privileges on any active subscription. 179 * 180 * <p>If the app does not have carrier privilege, this method will return {@code false} instead 181 * of throwing a SecurityException. Therefore, the callers cannot tell the difference 182 * between M+ apps which declare the runtime permission but do not have it, and pre-M apps 183 * which declare the static permission but had access revoked via AppOps. Apps in the former 184 * category expect SecurityExceptions; apps in the latter don't. So this method is suitable for 185 * use only if the behavior in both scenarios is meant to be identical. 186 * 187 * @return {@code true} if the app can read phone state or has carrier privilege; 188 * {@code false} otherwise. 189 */ checkReadPhoneStateOnAnyActiveSub(Context context, int pid, int uid, String callingPackage, @Nullable String callingFeatureId, String message)190 public static boolean checkReadPhoneStateOnAnyActiveSub(Context context, int pid, int uid, 191 String callingPackage, @Nullable String callingFeatureId, String message) { 192 try { 193 context.enforcePermission( 194 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message); 195 196 // SKIP checking for run-time permission since caller has PRIVILEGED permission 197 return true; 198 } catch (SecurityException privilegedPhoneStateException) { 199 try { 200 context.enforcePermission( 201 android.Manifest.permission.READ_PHONE_STATE, pid, uid, message); 202 } catch (SecurityException phoneStateException) { 203 // If we don't have the runtime permission, but do have carrier privileges, that 204 // suffices for reading phone state. 205 return checkCarrierPrivilegeForAnySubId(context, uid); 206 } 207 } 208 209 // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been 210 // revoked. 211 AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 212 return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage, 213 callingFeatureId, null) == AppOpsManager.MODE_ALLOWED; 214 } 215 216 /** 217 * Check whether the caller (or self, if not processing an IPC) can read device identifiers. 218 * 219 * <p>This method behaves in one of the following ways: 220 * <ul> 221 * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling 222 * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier 223 * access check, or the calling package has carrier privileges on any active subscription. 224 * <li>throw SecurityException: if the caller does not meet any of the requirements and is 225 * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission 226 * or carrier privileges of any active subscription. 227 * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE 228 * permission. In this case the caller would expect to have access to the device 229 * identifiers so false is returned instead of throwing a SecurityException to indicate 230 * the calling function should return placeholder data. 231 * </ul> 232 */ checkCallingOrSelfReadDeviceIdentifiers(Context context, String callingPackage, @Nullable String callingFeatureId, String message)233 public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, 234 String callingPackage, @Nullable String callingFeatureId, String message) { 235 return checkCallingOrSelfReadDeviceIdentifiers(context, 236 SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, callingFeatureId, 237 message); 238 } 239 240 /** 241 * Check whether the caller (or self, if not processing an IPC) can read device identifiers. 242 * 243 * <p>This method behaves in one of the following ways: 244 * <ul> 245 * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling 246 * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier 247 * access check, or the calling package has carrier privileges on any active 248 * subscription, or the calling package has the {@link 249 * Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} appop permission. 250 * <li>throw SecurityException: if the caller does not meet any of the requirements and is 251 * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission 252 * or carrier privileges of any active subscription. 253 * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE 254 * permission or carrier privileges. In this case the caller would expect to have access 255 * to the device identifiers so false is returned instead of throwing a SecurityException 256 * to indicate the calling function should return placeholder data. 257 * </ul> 258 */ checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message)259 public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId, 260 String callingPackage, @Nullable String callingFeatureId, String message) { 261 if (checkCallingOrSelfUseIccAuthWithDeviceIdentifier(context, callingPackage, 262 callingFeatureId, message)) { 263 return true; 264 } 265 return checkPrivilegedReadPermissionOrCarrierPrivilegePermission( 266 context, subId, callingPackage, callingFeatureId, message, true, true); 267 } 268 269 /** 270 * Check whether the caller (or self, if not processing an IPC) can read subscriber identifiers. 271 * 272 * <p>This method behaves in one of the following ways: 273 * <ul> 274 * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling 275 * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier 276 * access check, or the calling package has carrier privileges on specified subscription, 277 * or the calling package has the {@link 278 * Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} appop permission. 279 * <li>throw SecurityException: if the caller does not meet any of the requirements and is 280 * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission. 281 * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE 282 * permission. In this case the caller would expect to have access to the device 283 * identifiers so false is returned instead of throwing a SecurityException to indicate 284 * the calling function should return placeholder data. 285 * </ul> 286 */ checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message)287 public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId, 288 String callingPackage, @Nullable String callingFeatureId, String message) { 289 return checkCallingOrSelfReadSubscriberIdentifiers(context, subId, callingPackage, 290 callingFeatureId, message, true); 291 } 292 293 /** 294 * Same as {@link #checkCallingOrSelfReadSubscriberIdentifiers(Context, int, String, String, 295 * String)} except this allows an additional parameter reportFailure. Caller may not want to 296 * report a failure when this is an internal/intermediate check, for example, 297 * SubscriptionController calls this with an INVALID_SUBID to check if caller has the required 298 * permissions to bypass carrier privilege checks. 299 * @param reportFailure Indicates if failure should be reported. 300 */ checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message, boolean reportFailure)301 public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId, 302 String callingPackage, @Nullable String callingFeatureId, String message, 303 boolean reportFailure) { 304 if (checkCallingOrSelfUseIccAuthWithDeviceIdentifier(context, callingPackage, 305 callingFeatureId, message)) { 306 return true; 307 } 308 return checkPrivilegedReadPermissionOrCarrierPrivilegePermission( 309 context, subId, callingPackage, callingFeatureId, message, false, reportFailure); 310 } 311 throwSecurityExceptionAsUidDoesNotHaveAccess(String message, int uid)312 private static void throwSecurityExceptionAsUidDoesNotHaveAccess(String message, int uid) { 313 throw new SecurityException(message + ": The uid " + uid 314 + " does not meet the requirements to access device identifiers."); 315 } 316 317 /** 318 * Checks whether the app with the given pid/uid can read device identifiers. 319 * 320 * <p>This method behaves in one of the following ways: 321 * <ul> 322 * <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling 323 * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier 324 * access check; or the calling package has carrier privileges on the specified 325 * subscription; or allowCarrierPrivilegeOnAnySub is true and has carrier privilege on 326 * any active subscription. 327 * <li>throw SecurityException: if the caller does not meet any of the requirements and is 328 * targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission. 329 * <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE 330 * permission. In this case the caller would expect to have access to the device 331 * identifiers so false is returned instead of throwing a SecurityException to indicate 332 * the calling function should return placeholder data. 333 * </ul> 334 */ checkPrivilegedReadPermissionOrCarrierPrivilegePermission( Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message, boolean allowCarrierPrivilegeOnAnySub, boolean reportFailure)335 private static boolean checkPrivilegedReadPermissionOrCarrierPrivilegePermission( 336 Context context, int subId, String callingPackage, @Nullable String callingFeatureId, 337 String message, boolean allowCarrierPrivilegeOnAnySub, boolean reportFailure) { 338 int uid = Binder.getCallingUid(); 339 int pid = Binder.getCallingPid(); 340 341 // If the calling package has carrier privileges for specified sub, then allow access. 342 if (checkCarrierPrivilegeForSubId(context, subId)) return true; 343 344 // If the calling package has carrier privileges for any subscription 345 // and allowCarrierPrivilegeOnAnySub is set true, then allow access. 346 if (allowCarrierPrivilegeOnAnySub && checkCarrierPrivilegeForAnySubId(context, uid)) { 347 return true; 348 } 349 350 LegacyPermissionManager permissionManager = (LegacyPermissionManager) 351 context.getSystemService(Context.LEGACY_PERMISSION_SERVICE); 352 try { 353 if (permissionManager.checkDeviceIdentifierAccess(callingPackage, message, 354 callingFeatureId, 355 pid, uid) == PackageManager.PERMISSION_GRANTED) { 356 return true; 357 } 358 } catch (SecurityException se) { 359 throwSecurityExceptionAsUidDoesNotHaveAccess(message, uid); 360 } 361 362 if (reportFailure) { 363 return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage, 364 message); 365 } else { 366 return false; 367 } 368 } 369 370 /** 371 * Reports a failure when the app with the given pid/uid cannot access the requested identifier. 372 * 373 * @returns false if the caller is targeting pre-Q and does have the READ_PHONE_STATE 374 * permission or carrier privileges. 375 * @throws SecurityException if the caller does not meet any of the requirements for the 376 * requested identifier and is targeting Q or is targeting pre-Q 377 * and does not have the READ_PHONE_STATE permission or carrier 378 * privileges. 379 */ reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid, int uid, String callingPackage, String message)380 private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid, 381 int uid, String callingPackage, String message) { 382 ApplicationInfo callingPackageInfo = null; 383 try { 384 callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser( 385 callingPackage, 0, UserHandle.getUserHandleForUid(uid)); 386 } catch (PackageManager.NameNotFoundException e) { 387 // If the application info for the calling package could not be found then assume the 388 // calling app is a non-preinstalled app to detect any issues with the check 389 Log.e(LOG_TAG, "Exception caught obtaining package info for package " + callingPackage, 390 e); 391 } 392 // The current package should only be reported in StatsLog if it has not previously been 393 // reported for the currently invoked device identifier method. 394 boolean packageReported = sReportedDeviceIDPackages.containsKey(callingPackage); 395 if (!packageReported || !sReportedDeviceIDPackages.get(callingPackage).contains( 396 message)) { 397 Set invokedMethods; 398 if (!packageReported) { 399 invokedMethods = new HashSet<String>(); 400 sReportedDeviceIDPackages.put(callingPackage, invokedMethods); 401 } else { 402 invokedMethods = sReportedDeviceIDPackages.get(callingPackage); 403 } 404 invokedMethods.add(message); 405 TelephonyCommonStatsLog.write(TelephonyCommonStatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, 406 callingPackage, message, /* isPreinstalled= */ false, false); 407 } 408 Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message + ":" 409 + subId); 410 // if the target SDK is pre-Q then check if the calling package would have previously 411 // had access to device identifiers. 412 if (callingPackageInfo != null && ( 413 callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q)) { 414 if (context.checkPermission( 415 android.Manifest.permission.READ_PHONE_STATE, 416 pid, 417 uid) == PackageManager.PERMISSION_GRANTED) { 418 return false; 419 } 420 if (checkCarrierPrivilegeForSubId(context, subId)) { 421 return false; 422 } 423 } 424 throwSecurityExceptionAsUidDoesNotHaveAccess(message, uid); 425 return true; 426 } 427 428 /** 429 * Check whether the caller (or self, if not processing an IPC) has {@link 430 * Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} AppOp permission. 431 * 432 * <p>With the permission, the caller can access device/subscriber identifiers and use ICC 433 * authentication like EAP-AKA. 434 */ checkCallingOrSelfUseIccAuthWithDeviceIdentifier(Context context, String callingPackage, String callingFeatureId, String message)435 public static boolean checkCallingOrSelfUseIccAuthWithDeviceIdentifier(Context context, 436 String callingPackage, String callingFeatureId, String message) { 437 // The implementation follows PermissionChecker.checkAppOpPermission, but it cannot be 438 // used directly: because it uses noteProxyOpNoThrow which requires the phone process 439 // having the permission, which doesn't make sense since phone process is the ower of 440 // data/action. 441 // Cannot perform appop check if the calling package is null 442 if (callingPackage == null) { 443 return false; 444 } 445 int callingUid = Binder.getCallingUid(); 446 AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 447 int opMode = appOps.noteOpNoThrow(AppOpsManager.OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER, 448 callingUid, callingPackage, callingFeatureId, message); 449 switch (opMode) { 450 case AppOpsManager.MODE_ALLOWED: 451 case AppOpsManager.MODE_FOREGROUND: 452 return true; 453 case AppOpsManager.MODE_DEFAULT: 454 return context.checkCallingOrSelfPermission( 455 Manifest.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER) 456 == PERMISSION_GRANTED; 457 default: 458 return false; 459 } 460 } 461 462 /** 463 * Check whether the app with the given pid/uid can read the call log. 464 * @return {@code true} if the specified app has the read call log permission and AppOpp granted 465 * to it, {@code false} otherwise. 466 */ checkReadCallLog( Context context, int subId, int pid, int uid, String callingPackage, @Nullable String callingPackageName)467 public static boolean checkReadCallLog( 468 Context context, int subId, int pid, int uid, String callingPackage, 469 @Nullable String callingPackageName) { 470 if (context.checkPermission(Manifest.permission.READ_CALL_LOG, pid, uid) 471 != PERMISSION_GRANTED) { 472 // If we don't have the runtime permission, but do have carrier privileges, that 473 // suffices for being able to see the call phone numbers. 474 if (SubscriptionManager.isValidSubscriptionId(subId)) { 475 enforceCarrierPrivilege(context, subId, uid, "readCallLog"); 476 return true; 477 } 478 return false; 479 } 480 481 // We have READ_CALL_LOG permission, so return true as long as the AppOps bit hasn't been 482 // revoked. 483 AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); 484 return appOps.noteOp(AppOpsManager.OPSTR_READ_CALL_LOG, uid, callingPackage, 485 callingPackageName, null) == AppOpsManager.MODE_ALLOWED; 486 } 487 488 /** 489 * Returns whether the caller can read phone numbers. 490 * 491 * <p>Besides apps with the ability to read phone state per {@link #checkReadPhoneState} 492 * (only prior to R), the default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS 493 * can also read phone numbers. 494 */ checkCallingOrSelfReadPhoneNumber( Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message)495 public static boolean checkCallingOrSelfReadPhoneNumber( 496 Context context, int subId, String callingPackage, @Nullable String callingFeatureId, 497 String message) { 498 return checkReadPhoneNumber( 499 context, subId, Binder.getCallingPid(), Binder.getCallingUid(), 500 callingPackage, callingFeatureId, message); 501 } 502 503 /** 504 * Returns whether the caller can read phone numbers. 505 * 506 * <p>Besides apps with the ability to read phone state per {@link #checkReadPhoneState} 507 * (only prior to R), the default SMS app and apps with READ_SMS or READ_PHONE_NUMBERS 508 * can also read phone numbers. 509 */ 510 @VisibleForTesting checkReadPhoneNumber( Context context, int subId, int pid, int uid, String callingPackage, @Nullable String callingFeatureId, String message)511 public static boolean checkReadPhoneNumber( 512 Context context, int subId, int pid, int uid, 513 String callingPackage, @Nullable String callingFeatureId, String message) { 514 LegacyPermissionManager permissionManager = (LegacyPermissionManager) 515 context.getSystemService(Context.LEGACY_PERMISSION_SERVICE); 516 // Apps with target SDK version < R can have the READ_PHONE_STATE permission granted with 517 // the appop denied. If PERMISSION_GRANTED is not received then check if the caller has 518 // carrier privileges; if not and the permission result is MODE_IGNORED then return false 519 // to return null data to the caller. 520 int permissionResult = permissionManager.checkPhoneNumberAccess(callingPackage, message, 521 callingFeatureId, pid, uid); 522 if (permissionResult == PackageManager.PERMISSION_GRANTED) { 523 return true; 524 } 525 if (SubscriptionManager.isValidSubscriptionId(subId)) { 526 if (TelephonyPermissions.getCarrierPrivilegeStatus(context, subId, uid) 527 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 528 return true; 529 } 530 } 531 if (permissionResult == AppOpsManager.MODE_IGNORED) { 532 return false; 533 } 534 535 throw new SecurityException(message + ": Neither user " + uid 536 + " nor current process has " + android.Manifest.permission.READ_PHONE_STATE 537 + ", " + android.Manifest.permission.READ_SMS + ", or " 538 + android.Manifest.permission.READ_PHONE_NUMBERS); 539 } 540 541 /** 542 * Ensure the caller (or self, if not processing an IPC) has MODIFY_PHONE_STATE (and is thus a 543 * privileged app) or carrier privileges. 544 * 545 * @throws SecurityException if the caller does not have the required permission/privileges 546 */ enforceCallingOrSelfModifyPermissionOrCarrierPrivilege( Context context, int subId, String message)547 public static void enforceCallingOrSelfModifyPermissionOrCarrierPrivilege( 548 Context context, int subId, String message) { 549 if (context.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 550 == PERMISSION_GRANTED) { 551 return; 552 } 553 554 if (DBG) Log.d(LOG_TAG, "No modify permission, check carrier privilege next."); 555 enforceCallingOrSelfCarrierPrivilege(context, subId, message); 556 } 557 558 /** 559 * Ensure the caller (or self, if not processing an IPC) has 560 * {@link android.Manifest.permission#READ_PHONE_STATE} or carrier privileges. 561 * 562 * @throws SecurityException if the caller does not have the required permission/privileges 563 */ enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message)564 public static void enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege( 565 Context context, int subId, String message) { 566 if (context.checkCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE) 567 == PERMISSION_GRANTED) { 568 return; 569 } 570 571 if (DBG) { 572 Log.d(LOG_TAG, "No READ_PHONE_STATE permission, check carrier privilege next."); 573 } 574 575 enforceCallingOrSelfCarrierPrivilege(context, subId, message); 576 } 577 578 /** 579 * Ensure the caller (or self, if not processing an IPC) has 580 * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or carrier privileges. 581 * 582 * @throws SecurityException if the caller does not have the required permission/privileges 583 */ enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message)584 public static void enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege( 585 Context context, int subId, String message) { 586 if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) 587 == PERMISSION_GRANTED) { 588 return; 589 } 590 591 if (DBG) { 592 Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE permission, " 593 + "check carrier privilege next."); 594 } 595 596 enforceCallingOrSelfCarrierPrivilege(context, subId, message); 597 } 598 599 /** 600 * Ensure the caller (or self, if not processing an IPC) has 601 * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or 602 * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or carrier privileges. 603 * 604 * @throws SecurityException if the caller does not have the required permission/privileges 605 */ enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message)606 public static void enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( 607 Context context, int subId, String message) { 608 if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) 609 == PERMISSION_GRANTED) { 610 return; 611 } 612 613 if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) 614 == PERMISSION_GRANTED) { 615 return; 616 } 617 618 if (DBG) { 619 Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE nor READ_PRECISE_PHONE_STATE permission" 620 + ", check carrier privilege next."); 621 } 622 623 enforceCallingOrSelfCarrierPrivilege(context, subId, message); 624 } 625 626 /** 627 * Make sure the caller (or self, if not processing an IPC) has carrier privileges. 628 * 629 * @throws SecurityException if the caller does not have the required privileges 630 */ enforceCallingOrSelfCarrierPrivilege( Context context, int subId, String message)631 public static void enforceCallingOrSelfCarrierPrivilege( 632 Context context, int subId, String message) { 633 // NOTE: It's critical that we explicitly pass the calling UID here rather than call 634 // TelephonyManager#hasCarrierPrivileges directly, as the latter only works when called from 635 // the phone process. When called from another process, it will check whether that process 636 // has carrier privileges instead. 637 enforceCarrierPrivilege(context, subId, Binder.getCallingUid(), message); 638 } 639 enforceCarrierPrivilege( Context context, int subId, int uid, String message)640 private static void enforceCarrierPrivilege( 641 Context context, int subId, int uid, String message) { 642 if (getCarrierPrivilegeStatus(context, subId, uid) 643 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 644 if (DBG) Log.e(LOG_TAG, "No Carrier Privilege."); 645 throw new SecurityException(message); 646 } 647 } 648 649 /** Returns whether the provided uid has carrier privileges for any active subscription ID. */ checkCarrierPrivilegeForAnySubId(Context context, int uid)650 private static boolean checkCarrierPrivilegeForAnySubId(Context context, int uid) { 651 SubscriptionManager sm = (SubscriptionManager) context.getSystemService( 652 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 653 int[] activeSubIds = sm.getCompleteActiveSubscriptionIdList(); 654 for (int activeSubId : activeSubIds) { 655 if (getCarrierPrivilegeStatus(context, activeSubId, uid) 656 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 657 return true; 658 } 659 } 660 return false; 661 } 662 getCarrierPrivilegeStatus(Context context, int subId, int uid)663 private static int getCarrierPrivilegeStatus(Context context, int subId, int uid) { 664 if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) { 665 // Skip the check if it's one of these special uids 666 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; 667 } 668 final long identity = Binder.clearCallingIdentity(); 669 try { 670 TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService( 671 Context.TELEPHONY_SERVICE); 672 return telephonyManager.createForSubscriptionId(subId).getCarrierPrivilegeStatus(uid); 673 } finally { 674 Binder.restoreCallingIdentity(identity); 675 } 676 } 677 678 /** 679 * Given a list of permissions, check to see if the caller has at least one of them. If the 680 * caller has none of these permissions, throw a SecurityException. 681 */ enforceAnyPermissionGranted(Context context, int uid, String message, String... permissions)682 public static void enforceAnyPermissionGranted(Context context, int uid, String message, 683 String... permissions) { 684 if (permissions.length == 0) return; 685 boolean isGranted = false; 686 for (String perm : permissions) { 687 if (context.checkCallingOrSelfPermission(perm) == PERMISSION_GRANTED) { 688 isGranted = true; 689 break; 690 } 691 } 692 693 if (isGranted) return; 694 695 StringBuilder b = new StringBuilder(message); 696 b.append(": Neither user "); 697 b.append(uid); 698 b.append(" nor current process has "); 699 b.append(permissions[0]); 700 for (int i = 1; i < permissions.length; i++) { 701 b.append(" or "); 702 b.append(permissions[i]); 703 } 704 throw new SecurityException(b.toString()); 705 } 706 707 /** 708 * Given a list of permissions, check to see if the caller has at least one of them granted. If 709 * not, check to see if the caller has carrier privileges. If the caller does not have any of 710 * these permissions, throw a SecurityException. 711 */ enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, int uid, String message, String... permissions)712 public static void enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, 713 int uid, String message, String... permissions) { 714 if (permissions.length == 0) return; 715 boolean isGranted = false; 716 for (String perm : permissions) { 717 if (context.checkCallingOrSelfPermission(perm) == PERMISSION_GRANTED) { 718 isGranted = true; 719 break; 720 } 721 } 722 723 if (isGranted) return; 724 if (checkCarrierPrivilegeForSubId(context, subId)) return; 725 726 StringBuilder b = new StringBuilder(message); 727 b.append(": Neither user "); 728 b.append(uid); 729 b.append(" nor current process has "); 730 b.append(permissions[0]); 731 for (int i = 1; i < permissions.length; i++) { 732 b.append(" or "); 733 b.append(permissions[i]); 734 } 735 b.append(" or carrier privileges"); 736 throw new SecurityException(b.toString()); 737 } 738 739 /** 740 * Throws if the caller is not of a shell (or root) UID. 741 * 742 * @param callingUid pass Binder.callingUid(). 743 */ enforceShellOnly(int callingUid, String message)744 public static void enforceShellOnly(int callingUid, String message) { 745 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { 746 return; // okay 747 } 748 749 throw new SecurityException(message + ": Only shell user can call it"); 750 } 751 752 /** 753 * Returns the target SDK version number for a given package name. 754 * 755 * This call MUST be invoked before clearing the calling UID. 756 * 757 * @return target SDK if the package is found or INT_MAX. 758 */ getTargetSdk(Context c, String packageName)759 public static int getTargetSdk(Context c, String packageName) { 760 try { 761 final ApplicationInfo ai = c.getPackageManager().getApplicationInfoAsUser( 762 packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid())); 763 if (ai != null) return ai.targetSdkVersion; 764 } catch (PackageManager.NameNotFoundException unexpected) { 765 Log.e(LOG_TAG, "Failed to get package info for pkg=" 766 + packageName + ", uid=" + Binder.getCallingUid()); 767 } 768 return Integer.MAX_VALUE; 769 } 770 } 771