Merge "Merge QQ3A.200605.002 into master"
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 901c5ea..62ff07c 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -121,6 +121,7 @@
 
 import com.android.ims.ImsManager;
 import com.android.ims.internal.IImsServiceFeatureCallback;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.CallStateException;
@@ -1636,7 +1637,8 @@
     }
 
     /** Private constructor; @see init() */
-    private PhoneInterfaceManager(PhoneGlobals app) {
+    @VisibleForTesting
+    /* package */ PhoneInterfaceManager(PhoneGlobals app) {
         mApp = app;
         mCM = PhoneGlobals.getInstance().mCM;
         mImsResolver = PhoneGlobals.getInstance().getImsResolver();
@@ -7372,6 +7374,15 @@
 
     @Override
     public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
+        try {
+            PackageManager pm = mApp.getPackageManager();
+            if (Binder.getCallingUid() != pm.getPackageUid(callingPackage, 0)) {
+                throw new SecurityException("Calling package " + callingPackage + " does not match "
+                        + "calling UID");
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new SecurityException("Invalid calling package. e=" + e);
+        }
         boolean hasReadPermission = false;
         try {
             enforceReadPrivilegedPermission("getUiccCardsInfo");
diff --git a/tests/src/com/android/phone/LocationAccessPolicyTest.java b/tests/src/com/android/phone/LocationAccessPolicyTest.java
index 9938bf2..77ff158 100644
--- a/tests/src/com/android/phone/LocationAccessPolicyTest.java
+++ b/tests/src/com/android/phone/LocationAccessPolicyTest.java
@@ -146,6 +146,9 @@
         }
     }
 
+    private static final int TESTING_UID = 10001;
+    private static final int TESTING_PID = 8009;
+
     @Mock Context mContext;
     @Mock AppOpsManager mAppOpsManager;
     @Mock LocationManager mLocationManager;
@@ -194,15 +197,18 @@
                 anyInt(), anyString()))
                 .thenReturn(s.coarseAppOp);
 
+        // set this permission to denied by default, and only allow for the proper pid/uid
+        // combination
+        when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
+                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
         if (s.isDynamicLocationEnabled) {
             when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class))).thenReturn(true);
             when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
-                    anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+                    eq(TESTING_PID), eq(TESTING_UID)))
+                    .thenReturn(PackageManager.PERMISSION_GRANTED);
         } else {
             when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class)))
                     .thenReturn(false);
-            when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
-                    anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
         }
 
         ApplicationInfo fakeAppInfo = new ApplicationInfo();
@@ -220,8 +226,8 @@
         return new LocationAccessPolicy.LocationPermissionQuery.Builder()
                 .setMethod("test")
                 .setCallingPackage("com.android.test")
-                .setCallingPid(10001)
-                .setCallingUid(10001);
+                .setCallingPid(TESTING_PID)
+                .setCallingUid(TESTING_UID);
     }
 
     @Parameterized.Parameters(name = "{0}")
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
new file mode 100644
index 0000000..9f8de9e
--- /dev/null
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import static junit.framework.TestCase.fail;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.util.Log;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+public class PhoneInterfaceManagerTest extends TelephonyTestBase {
+
+    private static final String PRIVILEGED_PACKAGE_NAME = "test.package.name";
+
+    private static final String TAG = "PhoneInterfaceManagerTest";
+
+    private PhoneInterfaceManager mPhoneInterfaceManager;
+    private PhoneGlobals mMockPhoneGlobals;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        mMockPhoneGlobals = mock(PhoneGlobals.class);
+        //PhoneGlobals phoneGlobals = new PhoneGlobals(mContext);
+        mPhoneInterfaceManager = new PhoneInterfaceManager(mMockPhoneGlobals);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testGetUiccCardsInfoSecurity() {
+        // Set up mocks so that the supplied package UID does not equal the calling UID
+        PackageManager mockPackageManager = mock(PackageManager.class);
+        try {
+            doReturn(Binder.getCallingUid() + 1).when(mockPackageManager)
+                    .getPackageUid(eq(PRIVILEGED_PACKAGE_NAME), anyInt());
+        } catch (Exception e) {
+            Log.d(TAG, "testGetUiccCardsInfoSecurity unable to setup mocks");
+            fail();
+        }
+        doReturn(mockPackageManager).when(mContext).getPackageManager();
+        doReturn(mockPackageManager).when(mMockPhoneGlobals).getPackageManager();
+        try {
+            mPhoneInterfaceManager.getUiccCardsInfo(PRIVILEGED_PACKAGE_NAME);
+            fail();
+        } catch (SecurityException e) {
+            Log.d(TAG, "testGetUiccCardsInfoSecurity e = " + e);
+        }
+    }
+}