Check UID in getUiccCardsInfoSecurity
To avoid the case where a caller calls
PhoneInterfaceManager#getUiccCardsInfoSecurity using reflection and
supplies a calling package with privilege which isn't their own package,
we confirm that the calling package UID matches the supplied package.
Bug: 146570216
Test: atest com.android.phone.PhoneInterfaceManagerTest
Change-Id: Id08009f2feb281c20aaad55aa89faae66b709f88
Merged-In: Id08009f2feb281c20aaad55aa89faae66b709f88
(cherry picked from commit 102b27765aadb26935faa9b89bb0c784d019fd18)
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index d0ed9bd..2061796 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -113,6 +113,7 @@
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.ims.internal.IImsServiceFeatureCallback;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CallManager;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CarrierInfoManager;
@@ -1319,7 +1320,8 @@
}
/** Private constructor; @see init() */
- private PhoneInterfaceManager(PhoneGlobals app) {
+ @VisibleForTesting
+ /* package */ PhoneInterfaceManager(PhoneGlobals app) {
mApp = app;
mCM = PhoneGlobals.getInstance().mCM;
mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
@@ -6325,6 +6327,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/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);
+ }
+ }
+}