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