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