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