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