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