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