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