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.noteOp(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.noteOp(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.noteOp(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      */
checkLastKnownCellIdAccessPermission(Context context)601     public static boolean checkLastKnownCellIdAccessPermission(Context context) {
602         return context.checkCallingOrSelfPermission("android.permission.ACCESS_LAST_KNOWN_CELL_ID")
603                 == PackageManager.PERMISSION_GRANTED;
604     }
605 
606     /**
607      * Ensure the caller (or self, if not processing an IPC) has
608      * {@link android.Manifest.permission#READ_PHONE_STATE} or carrier privileges.
609      *
610      * @throws SecurityException if the caller does not have the required permission/privileges
611      */
enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message)612     public static void enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
613             Context context, int subId, String message) {
614         if (context.checkCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE)
615                 == PERMISSION_GRANTED) {
616             return;
617         }
618 
619         if (DBG) {
620             Log.d(LOG_TAG, "No READ_PHONE_STATE permission, check carrier privilege next.");
621         }
622 
623         enforceCallingOrSelfCarrierPrivilege(context, subId, message);
624     }
625 
626     /**
627      * Ensure the caller (or self, if not processing an IPC) has
628      * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or carrier privileges.
629      *
630      * @throws SecurityException if the caller does not have the required permission/privileges
631      */
enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message)632     public static void enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
633             Context context, int subId, String message) {
634         if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
635                 == PERMISSION_GRANTED) {
636             return;
637         }
638 
639         if (DBG) {
640             Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE permission, "
641                     + "check carrier privilege next.");
642         }
643 
644         enforceCallingOrSelfCarrierPrivilege(context, subId, message);
645     }
646 
647     /**
648      * Ensure the caller (or self, if not processing an IPC) has
649      * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
650      * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or carrier privileges.
651      *
652      * @throws SecurityException if the caller does not have the required permission/privileges
653      */
enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege( Context context, int subId, String message)654     public static void enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
655             Context context, int subId, String message) {
656         if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
657                 == PERMISSION_GRANTED) {
658             return;
659         }
660 
661         if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
662                 == PERMISSION_GRANTED) {
663             return;
664         }
665 
666         if (DBG) {
667             Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE nor READ_PRECISE_PHONE_STATE permission"
668                     + ", check carrier privilege next.");
669         }
670 
671         enforceCallingOrSelfCarrierPrivilege(context, subId, message);
672     }
673 
674     /**
675      * Make sure the caller (or self, if not processing an IPC) has carrier privileges.
676      *
677      * @throws SecurityException if the caller does not have the required privileges
678      */
enforceCallingOrSelfCarrierPrivilege( Context context, int subId, String message)679     public static void enforceCallingOrSelfCarrierPrivilege(
680             Context context, int subId, String message) {
681         // NOTE: It's critical that we explicitly pass the calling UID here rather than call
682         // TelephonyManager#hasCarrierPrivileges directly, as the latter only works when called from
683         // the phone process. When called from another process, it will check whether that process
684         // has carrier privileges instead.
685         enforceCarrierPrivilege(context, subId, Binder.getCallingUid(), message);
686     }
687 
enforceCarrierPrivilege( Context context, int subId, int uid, String message)688     private static void enforceCarrierPrivilege(
689             Context context, int subId, int uid, String message) {
690         if (getCarrierPrivilegeStatus(context, subId, uid)
691                 != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
692             if (DBG) Log.e(LOG_TAG, "No Carrier Privilege.");
693             throw new SecurityException(message);
694         }
695     }
696 
697     /** Returns whether the provided uid has carrier privileges for any active subscription ID. */
checkCarrierPrivilegeForAnySubId(Context context, int uid)698     private static boolean checkCarrierPrivilegeForAnySubId(Context context, int uid) {
699         SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
700                 Context.TELEPHONY_SUBSCRIPTION_SERVICE);
701         int[] activeSubIds;
702         final long identity = Binder.clearCallingIdentity();
703         try {
704             activeSubIds = sm.getCompleteActiveSubscriptionIdList();
705         } finally {
706             Binder.restoreCallingIdentity(identity);
707         }
708         for (int activeSubId : activeSubIds) {
709             if (getCarrierPrivilegeStatus(context, activeSubId, uid)
710                     == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
711                 return true;
712             }
713         }
714         return false;
715     }
716 
getCarrierPrivilegeStatus(Context context, int subId, int uid)717     private static int getCarrierPrivilegeStatus(Context context, int subId, int uid) {
718         if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
719             // Skip the check if it's one of these special uids
720             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
721         }
722         final long identity = Binder.clearCallingIdentity();
723         try {
724             TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
725                 Context.TELEPHONY_SERVICE);
726             return telephonyManager.createForSubscriptionId(subId).getCarrierPrivilegeStatus(uid);
727         } finally {
728             Binder.restoreCallingIdentity(identity);
729         }
730     }
731 
732     /**
733      * Given a list of permissions, check to see if the caller has at least one of them. If the
734      * caller has none of these permissions, throw a SecurityException.
735      */
enforceAnyPermissionGranted(Context context, int uid, String message, String... permissions)736     public static void enforceAnyPermissionGranted(Context context, int uid, String message,
737             String... permissions) {
738         if (permissions.length == 0) return;
739         boolean isGranted = false;
740         for (String perm : permissions) {
741             if (context.checkCallingOrSelfPermission(perm) == PERMISSION_GRANTED) {
742                 isGranted = true;
743                 break;
744             }
745         }
746 
747         if (isGranted) return;
748 
749         StringBuilder b = new StringBuilder(message);
750         b.append(": Neither user ");
751         b.append(uid);
752         b.append(" nor current process has ");
753         b.append(permissions[0]);
754         for (int i = 1; i < permissions.length; i++) {
755             b.append(" or ");
756             b.append(permissions[i]);
757         }
758         throw new SecurityException(b.toString());
759     }
760 
761     /**
762      * Given a list of permissions, check to see if the caller has at least one of them granted. If
763      * not, check to see if the caller has carrier privileges. If the caller does not have any of
764      * these permissions, throw a SecurityException.
765      */
enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, int uid, String message, String... permissions)766     public static void enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId,
767             int uid, String message, String... permissions) {
768         enforceAnyPermissionGrantedOrCarrierPrivileges(
769                 context, subId, uid, false, message, permissions);
770     }
771 
772     /**
773      * Given a list of permissions, check to see if the caller has at least one of them granted. If
774      * not, check to see if the caller has carrier privileges on the specified subscription (or any
775      * subscription if {@code allowCarrierPrivilegeOnAnySub} is {@code true}. If the caller does not
776      * have any of these permissions, throw a {@link SecurityException}.
777      */
enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId, int uid, boolean allowCarrierPrivilegeOnAnySub, String message, String... permissions)778     public static void enforceAnyPermissionGrantedOrCarrierPrivileges(Context context, int subId,
779             int uid, boolean allowCarrierPrivilegeOnAnySub, String message, String... permissions) {
780         if (permissions.length == 0) return;
781         boolean isGranted = false;
782         for (String perm : permissions) {
783             if (context.checkCallingOrSelfPermission(perm) == PERMISSION_GRANTED) {
784                 isGranted = true;
785                 break;
786             }
787         }
788 
789         if (isGranted) return;
790 
791         if (allowCarrierPrivilegeOnAnySub) {
792             if (checkCarrierPrivilegeForAnySubId(context, Binder.getCallingUid())) return;
793         } else {
794             if (checkCarrierPrivilegeForSubId(context, subId)) return;
795         }
796 
797         StringBuilder b = new StringBuilder(message);
798         b.append(": Neither user ");
799         b.append(uid);
800         b.append(" nor current process has ");
801         b.append(permissions[0]);
802         for (int i = 1; i < permissions.length; i++) {
803             b.append(" or ");
804             b.append(permissions[i]);
805         }
806         b.append(" or carrier privileges. subId=" + subId + ", allowCarrierPrivilegeOnAnySub="
807                 + allowCarrierPrivilegeOnAnySub);
808         throw new SecurityException(b.toString());
809     }
810 
811     /**
812      * Throws if the caller is not of a shell (or root) UID.
813      *
814      * @param callingUid pass Binder.callingUid().
815      */
enforceShellOnly(int callingUid, String message)816     public static void enforceShellOnly(int callingUid, String message) {
817         if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
818             return; // okay
819         }
820 
821         throw new SecurityException(message + ": Only shell user can call it");
822     }
823 
824     /**
825      * Returns the target SDK version number for a given package name.
826      *
827      * This call MUST be invoked before clearing the calling UID.
828      *
829      * @return target SDK if the package is found or INT_MAX.
830      */
getTargetSdk(Context c, String packageName)831     public static int getTargetSdk(Context c, String packageName) {
832         try {
833             final ApplicationInfo ai = c.getPackageManager().getApplicationInfoAsUser(
834                     packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
835             if (ai != null) return ai.targetSdkVersion;
836         } catch (PackageManager.NameNotFoundException unexpected) {
837             Log.e(LOG_TAG, "Failed to get package info for pkg="
838                     + packageName + ", uid=" + Binder.getCallingUid());
839         }
840         return Integer.MAX_VALUE;
841     }
842 
843     /**
844      * Check if calling user is associated with the given subscription.
845      * Subscription-user association check is skipped if destination address is an emergency number.
846      *
847      * @param context Context
848      * @param subId subscription ID
849      * @param callerUserHandle caller user handle
850      * @param destAddr destination address of the message
851      * @return  true if destAddr is an emergency number
852      * and return false if user is not associated with the subscription.
853      */
checkSubscriptionAssociatedWithUser(@onNull Context context, int subId, @NonNull UserHandle callerUserHandle, @NonNull String destAddr)854     public static boolean checkSubscriptionAssociatedWithUser(@NonNull Context context, int subId,
855             @NonNull UserHandle callerUserHandle, @NonNull String destAddr) {
856         // Skip subscription-user association check for emergency numbers
857         TelephonyManager tm = context.getSystemService(TelephonyManager.class);
858         final long token = Binder.clearCallingIdentity();
859         try {
860             if (tm != null && tm.isEmergencyNumber(destAddr)) {
861                 Log.d(LOG_TAG, "checkSubscriptionAssociatedWithUser:"
862                         + " destAddr is emergency number");
863                 return true;
864             }
865         } catch(Exception e) {
866             Log.e(LOG_TAG, "Cannot verify if destAddr is an emergency number: " + e);
867         } finally {
868             Binder.restoreCallingIdentity(token);
869         }
870 
871         return checkSubscriptionAssociatedWithUser(context, subId, callerUserHandle);
872     }
873 
874     /**
875      * Check if calling user is associated with the given subscription.
876      * @param context Context
877      * @param subId subscription ID
878      * @param callerUserHandle caller user handle
879      * @return  false if user is not associated with the subscription.
880      */
checkSubscriptionAssociatedWithUser(@onNull Context context, int subId, @NonNull UserHandle callerUserHandle)881     public static boolean checkSubscriptionAssociatedWithUser(@NonNull Context context, int subId,
882             @NonNull UserHandle callerUserHandle) {
883         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
884             // No subscription on device, return true.
885             return true;
886         }
887 
888         SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
889         final long token = Binder.clearCallingIdentity();
890         try {
891             if ((subManager != null) &&
892                     (!subManager.isSubscriptionAssociatedWithUser(subId, callerUserHandle))) {
893                 // If subId is not associated with calling user, return false.
894                 Log.e(LOG_TAG, "User[User ID:" + callerUserHandle.getIdentifier()
895                         + "] is not associated with Subscription ID:" + subId);
896                 return false;
897 
898             }
899         } finally {
900             Binder.restoreCallingIdentity(token);
901         }
902         return true;
903     }
904 
905     /**
906      * Ensure the caller (or self, if not processing an IPC) has
907      * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
908      * {@link android.Manifest.permission#READ_PHONE_NUMBERS}.
909      *
910      * @throws SecurityException if the caller does not have the required permission/privileges
911      */
912     @RequiresPermission(anyOf = {
913             android.Manifest.permission.READ_PHONE_NUMBERS,
914             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
915     })
checkCallingOrSelfReadPrivilegedPhoneStatePermissionOrReadPhoneNumber( Context context, int subId, String callingPackage, @Nullable String callingFeatureId, String message)916     public static boolean checkCallingOrSelfReadPrivilegedPhoneStatePermissionOrReadPhoneNumber(
917             Context context, int subId, String callingPackage, @Nullable String callingFeatureId,
918             String message) {
919         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
920             return false;
921         }
922         return (context.checkCallingOrSelfPermission(
923                 Manifest.permission.READ_PRIVILEGED_PHONE_STATE) == PERMISSION_GRANTED
924                 || checkCallingOrSelfReadPhoneNumber(context, subId, callingPackage,
925                 callingFeatureId, message));
926     }
927 }
928