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