Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8edd920 authored by Jeff Davidson's avatar Jeff Davidson Committed by Gerrit Code Review
Browse files

Merge "Factor out telephony permission checks into a helper class."

parents deee04be 01d1fd7d
Loading
Loading
Loading
Loading
+38 −92
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@

package com.android.internal.telephony;

import static android.Manifest.permission.CALL_PRIVILEGED;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;

import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.ImsiEncryptionInfo;
@@ -33,13 +35,6 @@ import com.android.internal.telephony.uicc.IsimRecords;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccCardApplication;

import static android.Manifest.permission.CALL_PRIVILEGED;
import static android.Manifest.permission.READ_PHONE_NUMBERS;
import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
import static android.Manifest.permission.READ_SMS;
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;

public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    private static final String TAG = "PhoneSubInfoController";
    private static final boolean DBG = true;
@@ -64,7 +59,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    }

    public String getDeviceIdForPhone(int phoneId, String callingPackage) {
        if (!checkReadPhoneState(callingPackage, "getDeviceId")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getDeviceId")) {
            return null;
        }
        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
@@ -82,7 +78,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getNaiForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getNai")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getNai")) {
                return null;
            }
            return phone.getNai();
@@ -95,7 +92,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getImeiForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getImei")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getImei")) {
                return null;
            }
            return phone.getImei();
@@ -109,7 +107,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
            String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getCarrierInfoForImsiEncryption")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getCarrierInfoForImsiEncryption")) {
                return null;
            }
            return phone.getCarrierInfoForImsiEncryption(keyType);
@@ -123,7 +122,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
                                                ImsiEncryptionInfo imsiEncryptionInfo) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "setCarrierInfoForImsiEncryption")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "setCarrierInfoForImsiEncryption")) {
                return;
            }
            phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo);
@@ -141,7 +141,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getDeviceSvnUsingSubId(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getDeviceSvn")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getDeviceSvn")) {
                return null;
            }
            return phone.getDeviceSvn();
@@ -158,7 +159,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getSubscriberIdForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getSubscriberId")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getSubscriberId")) {
                return null;
            }
            return phone.getSubscriberId();
@@ -178,7 +180,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getIccSerialNumberForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getIccSerialNumber")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getIccSerialNumber")) {
                return null;
            }
            return phone.getIccSerialNumber();
@@ -196,7 +199,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
        Phone phone = getPhone(subId);
        if (phone != null) {
            // This is open to apps with WRITE_SMS.
            if (!checkReadPhoneNumber(callingPackage, "getLine1Number")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
                    mContext, callingPackage, "getLine1Number")) {
                return null;
            }
            return phone.getLine1Number();
@@ -213,7 +217,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getLine1AlphaTag")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getLine1AlphaTag")) {
                return null;
            }
            return phone.getLine1AlphaTag();
@@ -230,7 +235,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getMsisdnForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getMsisdn")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getMsisdn")) {
                return null;
            }
            return phone.getMsisdn();
@@ -247,7 +253,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getVoiceMailNumber")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getVoiceMailNumber")) {
                return null;
            }
            String number = PhoneNumberUtils.extractNetworkPortion(phone.getVoiceMailNumber());
@@ -284,7 +291,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getVoiceMailAlphaTag")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getVoiceMailAlphaTag")) {
                return null;
            }
            return phone.getVoiceMailAlphaTag();
@@ -310,21 +318,14 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
     *
     * @throws SecurityException if the caller does not have the required permission/privilege
     */
    private void enforcePrivilegedPermissionOrCarrierPrivilege(Phone phone) {
    private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) {
        int permissionResult = mContext.checkCallingOrSelfPermission(
                READ_PRIVILEGED_PHONE_STATE);
        if (permissionResult == PackageManager.PERMISSION_GRANTED) {
            return;
        }
        log("No read privileged phone permission, check carrier privilege next.");
        UiccCard uiccCard = phone.getUiccCard();
        if (uiccCard == null) {
            throw new SecurityException("No Carrier Privilege: No UICC");
        }
        if (uiccCard.getCarrierPrivilegeStatusForCurrentTransaction(
                mContext.getPackageManager()) != CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
            throw new SecurityException("No Carrier Privilege.");
        }
        if (VDBG) log("No read privileged phone permission, check carrier privilege next.");
        TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, message);
    }

    private int getDefaultSubscription() {
@@ -434,8 +435,11 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {

    public String getIccSimChallengeResponse(int subId, int appType, int authType, String data)
            throws RemoteException {
        // TODO(b/73660190): Migrate to
        // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete
        // this helper method.
        enforcePrivilegedPermissionOrCarrierPrivilege(subId, "getIccSimChallengeResponse");
        Phone phone = getPhone(subId);
        enforcePrivilegedPermissionOrCarrierPrivilege(phone);
        UiccCard uiccCard = phone.getUiccCard();
        if (uiccCard == null) {
            loge("getIccSimChallengeResponse() UiccCard is null");
@@ -468,7 +472,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
    public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage) {
        Phone phone = getPhone(subId);
        if (phone != null) {
            if (!checkReadPhoneState(callingPackage, "getGroupIdLevel1")) {
            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                    mContext, callingPackage, "getGroupIdLevel1")) {
                return null;
            }
            return phone.getGroupIdLevel1();
@@ -478,65 +483,6 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
        }
    }

    private boolean checkReadPhoneState(String callingPackage, String message) {
        try {
            mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message);

            // SKIP checking run-time OP_READ_PHONE_STATE since self or using PRIVILEGED
            return true;
        } catch (SecurityException e) {
            mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, message);
        }

        return mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
                callingPackage) == AppOpsManager.MODE_ALLOWED;
    }

    /**
     * Besides READ_PHONE_STATE, READ_PHONE_NUMBERS, WRITE_SMS and READ_SMS also allow apps to get
     * phone numbers.
     */
    private boolean checkReadPhoneNumber(String callingPackage, String message) {
        // Default SMS app can always read it.
        if (mAppOps.noteOp(AppOpsManager.OP_WRITE_SMS,
                Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED) {
            return true;
        }
        try {
            return checkReadPhoneState(callingPackage, message);
        } catch (SecurityException readPhoneStateSecurityException) {
        }
        try {
            // Can be read with READ_SMS too.
            mContext.enforceCallingOrSelfPermission(READ_SMS, message);
            int opCode = mAppOps.permissionToOpCode(READ_SMS);
            if (opCode != AppOpsManager.OP_NONE) {
                return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage)
                        == AppOpsManager.MODE_ALLOWED;
            } else {
                return true;
            }
        } catch (SecurityException readSmsSecurityException) {
        }
        try {
            // Can be read with READ_PHONE_NUMBERS too.
            mContext.enforceCallingOrSelfPermission(READ_PHONE_NUMBERS, message);
            int opCode = mAppOps.permissionToOpCode(READ_PHONE_NUMBERS);
            if (opCode != AppOpsManager.OP_NONE) {
                return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage)
                        == AppOpsManager.MODE_ALLOWED;
            } else {
                return true;
            }
        } catch (SecurityException readPhoneNumberSecurityException) {
        }
        // Throw exception with message including READ_PHONE_STATE, READ_SMS, and READ_PHONE_NUMBERS
        // permissions
        throw new SecurityException(message + ": Neither user " + Binder.getCallingUid() +
                " nor current process has " + READ_PHONE_STATE + ", " +
                READ_SMS + ", or " + READ_PHONE_STATE + ".");
    }

    private void log(String s) {
        Rlog.d(TAG, s);
    }
+20 −37
Original line number Diff line number Diff line
@@ -232,32 +232,6 @@ public class SubscriptionController extends ISub.Stub {
        if (DBG) logdl("[SubscriptionController] init by Phone");
    }

    /**
     * Make sure the caller can read phone state which requires holding the
     * READ_PHONE_STATE permission and the OP_READ_PHONE_STATE app op being
     * set to MODE_ALLOWED.
     *
     * @param callingPackage The package claiming to make the IPC.
     * @param message The name of the access protected method.
     *
     * @throws SecurityException if the caller does not have READ_PHONE_STATE permission.
     */
    private boolean canReadPhoneState(String callingPackage, String message) {
        try {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);

            // SKIP checking run-time permission since self or using PRIVILEDGED permission
            return true;
        } catch (SecurityException e) {
            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
                    message);
        }

        return mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
                callingPackage) == AppOpsManager.MODE_ALLOWED;
    }

    private void enforceModifyPhoneState(String message) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.MODIFY_PHONE_STATE, message);
@@ -443,7 +417,8 @@ public class SubscriptionController extends ISub.Stub {
     */
    @Override
    public SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage) {
        if (!canReadPhoneState(callingPackage, "getActiveSubscriptionInfo")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getActiveSubscriptionInfo")) {
            return null;
        }

@@ -482,8 +457,8 @@ public class SubscriptionController extends ISub.Stub {
     */
    @Override
    public SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage) {
        if (!canReadPhoneState(callingPackage, "getActiveSubscriptionInfoForIccId") ||
                iccId == null) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getActiveSubscriptionInfoForIccId") || iccId == null) {
            return null;
        }

@@ -521,7 +496,8 @@ public class SubscriptionController extends ISub.Stub {
    @Override
    public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex,
            String callingPackage) {
        if (!canReadPhoneState(callingPackage, "getActiveSubscriptionInfoForSimSlotIndex")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getActiveSubscriptionInfoForSimSlotIndex")) {
            return null;
        }

@@ -566,7 +542,8 @@ public class SubscriptionController extends ISub.Stub {
    public List<SubscriptionInfo> getAllSubInfoList(String callingPackage) {
        if (DBG) logd("[getAllSubInfoList]+");

        if (!canReadPhoneState(callingPackage, "getAllSubInfoList")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getAllSubInfoList")) {
            return null;
        }

@@ -594,7 +571,8 @@ public class SubscriptionController extends ISub.Stub {
    @Override
    public List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage) {

        if (!canReadPhoneState(callingPackage, "getActiveSubscriptionInfoList")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getActiveSubscriptionInfoList")) {
            return null;
        }

@@ -677,7 +655,8 @@ public class SubscriptionController extends ISub.Stub {
     */
    @Override
    public int getActiveSubInfoCount(String callingPackage) {
        if (!canReadPhoneState(callingPackage, "getActiveSubInfoCount")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getActiveSubInfoCount")) {
            return 0;
        }

@@ -706,7 +685,8 @@ public class SubscriptionController extends ISub.Stub {
    public int getAllSubInfoCount(String callingPackage) {
        if (DBG) logd("[getAllSubInfoCount]+");

        if (!canReadPhoneState(callingPackage, "getAllSubInfoCount")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getAllSubInfoCount")) {
            return 0;
        }

@@ -745,7 +725,8 @@ public class SubscriptionController extends ISub.Stub {

    @Override
    public List<SubscriptionInfo> getAvailableSubscriptionInfoList(String callingPackage) {
        if (!canReadPhoneState(callingPackage, "getAvailableSubscriptionInfoList")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getAvailableSubscriptionInfoList")) {
            throw new SecurityException("Need READ_PHONE_STATE to call "
                    + " getAvailableSubscriptionInfoList");
        }
@@ -1885,7 +1866,8 @@ public class SubscriptionController extends ISub.Stub {
                                                                    boolean needCheck,
                                                                    String callingPackage) {
        if (DBG) logd("[getSubInfoUsingSlotIndexWithCheck]+ slotIndex:" + slotIndex);
        if (!canReadPhoneState(callingPackage, "getSubInfoUsingSlotIndexWithCheck")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getSubInfoUsingSlotIndexWithCheck")) {
            return null;
        }

@@ -2076,7 +2058,8 @@ public class SubscriptionController extends ISub.Stub {
     */
    @Override
    public String getSubscriptionProperty(int subId, String propKey, String callingPackage) {
        if (!canReadPhoneState(callingPackage, "getSubInfoUsingSlotIndexWithCheck")) {
        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                mContext, callingPackage, "getSubInfoUsingSlotIndexWithCheck")) {
            return null;
        }
        String resultValue = null;
+12 −1
Original line number Diff line number Diff line
@@ -337,7 +337,18 @@ public class UiccCarrierPrivilegeRules extends Handler {
     * @return Access status.
     */
    public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) {
        String[] packages = packageManager.getPackagesForUid(Binder.getCallingUid());
        return getCarrierPrivilegeStatusForUid(packageManager, Binder.getCallingUid());
    }

    /**
     * Returns the status of the carrier privileges for the caller of the current transaction.
     *
     * @param packageManager PackageManager for getting signatures and package names.
     * @return Access status.
     */
    public int getCarrierPrivilegeStatusForUid(
            PackageManager packageManager, int uid) {
        String[] packages = packageManager.getPackagesForUid(uid);

        for (String pkg : packages) {
            int accessStatus = getCarrierPrivilegeStatus(packageManager, pkg);
+10 −0
Original line number Diff line number Diff line
@@ -1303,6 +1303,16 @@ public class UiccProfile extends Handler implements IccCard {
                        packageManager);
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForUid}.
     */
    public int getCarrierPrivilegeStatusForUid(PackageManager packageManager, int uid) {
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules == null
                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
                carrierPrivilegeRules.getCarrierPrivilegeStatusForUid(packageManager, uid);
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
     */
+10 −0
Original line number Diff line number Diff line
@@ -451,6 +451,11 @@ public class ContextFixture implements TestFixture<Context> {
            throw new SecurityException(permission + " denied: " + message);
        }

        @Override
        public void enforcePermission(String permission, int pid, int uid, String message) {
            enforceCallingOrSelfPermission(permission, message);
        }

        @Override
        public int checkCallingOrSelfPermission(String permission) {
            if (mPermissionTable.contains(permission)
@@ -463,6 +468,11 @@ public class ContextFixture implements TestFixture<Context> {
            }
        }

        @Override
        public int checkPermission(String permission, int pid, int uid) {
            return checkCallingOrSelfPermission(permission);
        }

        @Override
        public SharedPreferences getSharedPreferences(String name, int mode) {
            return mSharedPreferences;
Loading