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