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 (isSystemOrPhone(uid)) { 720 // Skip the check if it's one of these special uids 721 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; 722 } 723 724 final long identity = Binder.clearCallingIdentity(); 725 try { 726 TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService( 727 Context.TELEPHONY_SERVICE); 728 return telephonyManager.createForSubscriptionId(subId).getCarrierPrivilegeStatus(uid); 729 } finally { 730 Binder.restoreCallingIdentity(identity); 731 } 732 } 733 734 /** 735 * Given a list of permissions, check to see if the caller has at least one of them. If the 736 * caller has none of these permissions, throw a SecurityException. 737 */ enforceAnyPermissionGranted(Context context, int uid, String message, String... permissions)738 public static void enforceAnyPermissionGranted(Context context, int uid, String message, 739 String... permissions) { 740 if (permissions.length == 0) return; 741 boolean isGranted = false; 742 for (String perm : permissions) { 743 if (context.checkCallingOrSelfPermission(perm) == PERMISSION_GRANTED) { 744 isGranted = true; 745 break; 746 } 747 } 748 749 if (isGranted) return; 750 751 StringBuilder b = new StringBuilder(message); 752 b.append(": Neither user "); 753 b.append(uid); 754 b.append(" nor current process has "); 755 b.append(permissions[0]); 756 for (int i = 1; i < permissions.length; i++) { 757 b.append(" or "); 758 b.append(permissions[i]); 759 } 760 throw new SecurityException(b.toString()); 761 } 762 763 /** 764 * Given a list of permissions, check to see if the caller has at least one of them granted. If 765 * not, check to see if the caller has carrier privileges. If the caller does not have any of 766 * these permissions, throw a SecurityException. 767 */ enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, int uid, String message, String... permissions)768 public static void enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, 769 int uid, String message, String... permissions) { 770 enforceAnyPermissionGrantedOrCarrierPrivileges( 771 context, subId, uid, false, message, permissions); 772 } 773 774 /** 775 * Given a list of permissions, check to see if the caller has at least one of them granted. If 776 * not, check to see if the caller has carrier privileges on the specified subscription (or any 777 * subscription if {@code allowCarrierPrivilegeOnAnySub} is {@code true}. If the caller does not 778 * have any of these permissions, throw a {@link SecurityException}. 779 */ enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, int uid, boolean allowCarrierPrivilegeOnAnySub, String message, String... permissions)780 public static void enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, 781 int uid, boolean allowCarrierPrivilegeOnAnySub, String message, String... permissions) { 782 if (permissions.length == 0) return; 783 boolean isGranted = false; 784 for (String perm : permissions) { 785 if (context.checkCallingOrSelfPermission(perm) == PERMISSION_GRANTED) { 786 isGranted = true; 787 break; 788 } 789 } 790 791 if (isGranted) return; 792 793 if (allowCarrierPrivilegeOnAnySub) { 794 if (checkCarrierPrivilegeForAnySubId(context, uid)) return; 795 } else { 796 if (checkCarrierPrivilegeForSubId(context, subId)) return; 797 } 798 799 StringBuilder b = new StringBuilder(message); 800 b.append(": Neither user "); 801 b.append(uid); 802 b.append(" nor current process has "); 803 b.append(permissions[0]); 804 for (int i = 1; i < permissions.length; i++) { 805 b.append(" or "); 806 b.append(permissions[i]); 807 } 808 b.append(" or carrier privileges. subId=" + subId + ", allowCarrierPrivilegeOnAnySub=" 809 + allowCarrierPrivilegeOnAnySub); 810 throw new SecurityException(b.toString()); 811 } 812 813 /** 814 * Throws if the caller is not of a shell (or root) UID. 815 * 816 * @param callingUid pass Binder.callingUid(). 817 */ enforceShellOnly(int callingUid, String message)818 public static void enforceShellOnly(int callingUid, String message) { 819 if (UserHandle.isSameApp(callingUid, Process.SHELL_UID) 820 || UserHandle.isSameApp(callingUid, Process.ROOT_UID)) { 821 return; // okay 822 } 823 824 throw new SecurityException(message + ": Only shell user can call it"); 825 } 826 827 /** 828 * Returns the target SDK version number for a given package name. 829 * 830 * This call MUST be invoked before clearing the calling UID. 831 * 832 * @return target SDK if the package is found or INT_MAX. 833 */ getTargetSdk(Context c, String packageName)834 public static int getTargetSdk(Context c, String packageName) { 835 try { 836 final ApplicationInfo ai = c.getPackageManager().getApplicationInfoAsUser( 837 packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid())); 838 if (ai != null) return ai.targetSdkVersion; 839 } catch (PackageManager.NameNotFoundException unexpected) { 840 Log.e(LOG_TAG, "Failed to get package info for pkg=" 841 + packageName + ", uid=" + Binder.getCallingUid()); 842 } 843 return Integer.MAX_VALUE; 844 } 845 846 /** 847 * Check if calling user is associated with the given subscription. 848 * Subscription-user association check is skipped if destination address is an emergency number. 849 * 850 * @param context Context 851 * @param subId subscription ID 852 * @param callerUserHandle caller user handle 853 * @param destAddr destination address of the message 854 * @return true if destAddr is an emergency number 855 * and return false if user is not associated with the subscription. 856 */ checkSubscriptionAssociatedWithUser(@onNull Context context, int subId, @NonNull UserHandle callerUserHandle, @NonNull String destAddr)857 public static boolean checkSubscriptionAssociatedWithUser(@NonNull Context context, int subId, 858 @NonNull UserHandle callerUserHandle, @NonNull String destAddr) { 859 // Skip subscription-user association check for emergency numbers 860 TelephonyManager tm = (TelephonyManager) context.getSystemService( 861 Context.TELEPHONY_SERVICE); 862 final long token = Binder.clearCallingIdentity(); 863 try { 864 if (tm != null && tm.isEmergencyNumber(destAddr)) { 865 Log.d(LOG_TAG, "checkSubscriptionAssociatedWithUser:" 866 + " destAddr is emergency number"); 867 return true; 868 } 869 } catch(Exception e) { 870 Log.e(LOG_TAG, "Cannot verify if destAddr is an emergency number: " + e); 871 } finally { 872 Binder.restoreCallingIdentity(token); 873 } 874 875 return checkSubscriptionAssociatedWithUser(context, subId, callerUserHandle); 876 } 877 878 /** 879 * Check if calling user is associated with the given subscription. 880 * @param context Context 881 * @param subId subscription ID 882 * @param callerUserHandle caller user handle 883 * @return false if user is not associated with the subscription, or no record found of this 884 * subscription. 885 */ checkSubscriptionAssociatedWithUser(@onNull Context context, int subId, @NonNull UserHandle callerUserHandle)886 public static boolean checkSubscriptionAssociatedWithUser(@NonNull Context context, int subId, 887 @NonNull UserHandle callerUserHandle) { 888 SubscriptionManager subManager = (SubscriptionManager) context.getSystemService( 889 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 890 final long token = Binder.clearCallingIdentity(); 891 try { 892 if ((subManager != null) && 893 (!subManager.isSubscriptionAssociatedWithUser(subId, callerUserHandle))) { 894 // If subId is not associated with calling user, return false. 895 Log.e(LOG_TAG, "User[User ID:" + callerUserHandle.getIdentifier() 896 + "] is not associated with Subscription ID:" + subId); 897 return false; 898 } 899 } catch (IllegalArgumentException e) { 900 // Found no record of this sub Id. 901 Log.e(LOG_TAG, "Subscription[Subscription ID:" + subId + "] has no records on device"); 902 return false; 903 } finally { 904 Binder.restoreCallingIdentity(token); 905 } 906 return true; 907 } 908 909 /** 910 * @return true if the specified {@code uid} is for a system or phone process, no matter if runs 911 * as system user or not. 912 */ isSystemOrPhone(int uid)913 public static boolean isSystemOrPhone(int uid) { 914 return UserHandle.isSameApp(uid, Process.SYSTEM_UID) || UserHandle.isSameApp(uid, 915 Process.PHONE_UID); 916 } 917 918 /** 919 * @return true if the specified {@code uid} is for a ROOT or SHELL process, no matter if runs 920 * as system user or not. 921 */ isRootOrShell(int uid)922 public static boolean isRootOrShell(int uid) { 923 return UserHandle.isSameApp(uid, Process.ROOT_UID) || UserHandle.isSameApp(uid, 924 Process.SHELL_UID); 925 } 926 } 927