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

Commit 8bd5ee16 authored by Xiangyu/Malcolm Chen's avatar Xiangyu/Malcolm Chen Committed by Gerrit Code Review
Browse files

Merge "Don't allow reading IMSI of one active sub if only has carrier privilege on the other."

parents b9d188ed 66df384e
Loading
Loading
Loading
Loading
+98 −24
Original line number Diff line number Diff line
@@ -32,8 +32,11 @@ import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ServiceManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
@@ -50,14 +53,15 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.lang.reflect.Field;
import java.util.Map;

@SmallTest
public class TelephonyPermissionsTest {

    private static final int SUB_ID = 55555;
    private static final int SUB_ID_2 = 22222;
    private static final int PID = 12345;
    private static final int UID = 54321;
    private static final int PID = Binder.getCallingPid();
    private static final int UID = Binder.getCallingUid();
    private static final String PACKAGE = "com.example";
    private static final String MSG = "message";

@@ -70,6 +74,8 @@ public class TelephonyPermissionsTest {
    @Mock
    private ITelephony mMockTelephony;
    @Mock
    private IBinder mMockTelephonyBinder;
    @Mock
    private PackageManager mMockPackageManager;
    @Mock
    private ApplicationInfo mMockApplicationInfo;
@@ -101,10 +107,13 @@ public class TelephonyPermissionsTest {
                AppOpsManager.MODE_ERRORED);
        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS);
        when(mMockContext.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                PID, UID)).thenReturn(PackageManager.PERMISSION_DENIED);
        when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), eq(PID),
                eq(UID))).thenReturn(false);
        setTelephonyMockAsService();
    }

    @Test
@@ -243,8 +252,8 @@ public class TelephonyPermissionsTest {
    public void testCheckReadDeviceIdentifiers_noPermissions() throws Exception {
        setupMocksForDeviceIdentifiersErrorPath();
        try {
            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                    SUB_ID, PID, UID, PACKAGE, MSG);
            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                    SUB_ID, PACKAGE, MSG);
            fail("Should have thrown SecurityException");
        } catch (SecurityException e) {
            // expected
@@ -256,8 +265,8 @@ public class TelephonyPermissionsTest {
        when(mMockContext.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
                PID, UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
        assertTrue(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -265,8 +274,8 @@ public class TelephonyPermissionsTest {
        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), eq(UID)))
                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
        assertTrue(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -274,8 +283,8 @@ public class TelephonyPermissionsTest {
        when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
                PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
        assertTrue(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -283,8 +292,8 @@ public class TelephonyPermissionsTest {
        when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), eq(PID),
                eq(UID))).thenReturn(true);
        assertTrue(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -296,8 +305,8 @@ public class TelephonyPermissionsTest {
                UID)).thenReturn(PackageManager.PERMISSION_GRANTED);
        setupMocksForDeviceIdentifiersErrorPath();
        try {
            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                    SUB_ID, PID, UID, PACKAGE, MSG);
            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                    SUB_ID, PACKAGE, MSG);
            fail("Should have thrown SecurityException");
        } catch (SecurityException e) {
            // expected
@@ -314,8 +323,8 @@ public class TelephonyPermissionsTest {
        setupMocksForDeviceIdentifiersErrorPath();
        mMockApplicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
        assertFalse(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -326,8 +335,8 @@ public class TelephonyPermissionsTest {
        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID))).thenReturn(
                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
        assertTrue(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -340,8 +349,8 @@ public class TelephonyPermissionsTest {
        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), eq(UID)))
                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
        assertTrue(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID_2, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -354,8 +363,8 @@ public class TelephonyPermissionsTest {
        when(mMockAppOps.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, UID,
                PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
        assertTrue(
                TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                        SUB_ID, PID, UID, PACKAGE, MSG));
                TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
@@ -365,14 +374,79 @@ public class TelephonyPermissionsTest {
        // case.
        setupMocksForDeviceIdentifiersErrorPath();
        try {
            TelephonyPermissions.checkReadDeviceIdentifiers(mMockContext, () -> mMockTelephony,
                    SUB_ID, PID, UID, null, MSG);
            TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mMockContext,
                    SUB_ID, null, MSG);
            fail("Should have thrown SecurityException");
        } catch (SecurityException e) {
            // expected
        }
    }

    @Test
    public void testCheckCallingOrSelfReadSubscriberIdentifiers_noPermissions() throws Exception {
        setupMocksForDeviceIdentifiersErrorPath();
        setTelephonyMockAsService();
        when(mMockContext.checkPermission(
                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
        when(mMockAppOps.noteOpNoThrow(anyString(), anyInt(), eq(PACKAGE))).thenReturn(
                AppOpsManager.MODE_ERRORED);
        when(mMockDevicePolicyManager.checkDeviceIdentifierAccess(eq(PACKAGE), anyInt(),
                anyInt())).thenReturn(false);
        try {
            TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
                    SUB_ID, PACKAGE, MSG);
            fail("Should have thrown SecurityException");
        } catch (SecurityException e) {
            // expected
        }
    }

    @Test
    public void testCheckCallingOrSelfReadSubscriberIdentifiers_carrierPrivileges()
            throws Exception {
        setTelephonyMockAsService();
        when(mMockContext.checkPermission(
                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID), anyInt()))
                .thenReturn(TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
        assertTrue(
                TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
                        SUB_ID, PACKAGE, MSG));
    }

    @Test
    public void testCheckCallingOrSelfReadSubscriberIdentifiers_carrierPrivilegesOnOtherSub()
            throws Exception {
        setupMocksForDeviceIdentifiersErrorPath();
        setTelephonyMockAsService();
        when(mMockContext.checkPermission(
                eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
        when(mMockSubscriptionManager.getActiveSubscriptionIdList(anyBoolean())).thenReturn(
                new int[]{SUB_ID, SUB_ID_2});
        when(mMockTelephony.getCarrierPrivilegeStatusForUid(eq(SUB_ID_2), anyInt())).thenReturn(
                TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
        // Carrier privilege on the other active sub shouldn't allow access to this sub.
        try {
            TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mMockContext,
                    SUB_ID, PACKAGE, MSG);
            fail("Should have thrown SecurityException");
        } catch (SecurityException e) {
            // expected
        }
    }

    // Put mMockTelephony into service cache so that TELEPHONY_SUPPLIER will get it.
    private void setTelephonyMockAsService() throws Exception {
        when(mMockTelephonyBinder.queryLocalInterface(anyString())).thenReturn(mMockTelephony);
        Field field = ServiceManager.class.getDeclaredField("sCache");
        field.setAccessible(true);
        ((Map<String, IBinder>) field.get(null)).put(Context.TELEPHONY_SERVICE,
                mMockTelephonyBinder);
    }

    public static class FakeSettingsConfigProvider extends FakeSettingsProvider {
        private static final String PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED =
                DeviceConfig.NAMESPACE_PRIVACY + "/"