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