Add callingPackage checking with uid in getPhoneAccount method in Telecom

Test: manual verified with test app; unit test
Bug: 196406138
Change-Id: I2cfa653e619f522fecdcd01cd080078f6a1ab1f3
Merged-In: I2cfa653e619f522fecdcd01cd080078f6a1ab1f3
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 8d6e324..7d6d974 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -284,7 +284,7 @@
         public List<PhoneAccountHandle> getPhoneAccountsForPackage(String packageName) {
             //TODO: Deprecate this in S
             try {
-                enforceCallingPackage(packageName);
+                enforceCallingPackage(packageName, "getPhoneAccountsForPackage");
             } catch (SecurityException se1) {
                 EventLog.writeEvent(0x534e4554, "153995334", Binder.getCallingUid(),
                         "getPhoneAccountsForPackage: invalid calling package");
@@ -319,6 +319,14 @@
         @Override
         public PhoneAccount getPhoneAccount(PhoneAccountHandle accountHandle,
                 String callingPackage) {
+            try {
+                enforceCallingPackage(callingPackage, "getPhoneAccount");
+            } catch (SecurityException se) {
+                EventLog.writeEvent(0x534e4554, "196406138", Binder.getCallingUid(),
+                        "getPhoneAccount: invalid calling package");
+                throw se;
+            }
+
             synchronized (mLock) {
                 final UserHandle callingUserHandle = Binder.getCallingUserHandle();
                 if (CompatChanges.isChangeEnabled(
@@ -852,7 +860,7 @@
         public boolean hasManageOngoingCallsPermission(String callingPackage) {
             try {
                 Log.startSession("TSI.hMOCP");
-                enforceCallingPackage(callingPackage);
+                enforceCallingPackage(callingPackage, "hasManageOngoingCallsPermission");
                 return PermissionChecker.checkPermissionForDataDeliveryFromDataSource(
                         mContext, Manifest.permission.MANAGE_ONGOING_CALLS,
                         Binder.getCallingPid(),
@@ -1464,7 +1472,7 @@
                 String callingFeatureId) {
             try {
                 Log.startSession("TSI.pC", Log.getPackageAbbreviation(callingPackage));
-                enforceCallingPackage(callingPackage);
+                enforceCallingPackage(callingPackage, "placeCall");
 
                 PhoneAccountHandle phoneAccountHandle = null;
                 boolean clearPhoneAccountHandleExtra = false;
@@ -2229,7 +2237,7 @@
             // feature is enabled ...
             enforceConnectionServiceFeature();
             // ... and the PhoneAccounts they refer to are for their own package.
-            enforceCallingPackage(packageName);
+            enforceCallingPackage(packageName, "enforcePhoneAccountModificationForPackage");
         }
     }
 
@@ -2245,8 +2253,22 @@
         }
     }
 
-    private void enforceCallingPackage(String packageName) {
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
+    private void enforceCallingPackage(String packageName, String message) {
+        int packageUid = -1;
+        int callingUid = Binder.getCallingUid();
+        PackageManager pm = mContext.createContextAsUser(
+            UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
+        if (pm != null) {
+            try {
+                packageUid = pm.getPackageUid(packageName, 0);
+            } catch (PackageManager.NameNotFoundException e) {
+                // packageUid is -1
+            }
+        }
+        if (packageUid != callingUid && callingUid != Process.ROOT_UID) {
+            throw new SecurityException(message + ": Package " + packageName
+                + " does not belong to " + callingUid);
+        }
     }
 
     private void enforceConnectionServiceFeature() {
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 3cec50b..8a84064 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -102,6 +102,7 @@
 public class TelecomServiceImplTest extends TelecomTestCase {
 
     public static final String TEST_PACKAGE = "com.test";
+    public static final String PACKAGE_NAME = "test";
 
     public static class CallIntentProcessAdapterFake implements CallIntentProcessor.Adapter {
         @Override
@@ -180,15 +181,17 @@
     private static final UserHandle USER_HANDLE_16 = new UserHandle(16);
     private static final UserHandle USER_HANDLE_17 = new UserHandle(17);
     private static final PhoneAccountHandle TEL_PA_HANDLE_16 = new PhoneAccountHandle(
-            new ComponentName("test", "telComponentName"), "0", USER_HANDLE_16);
+            new ComponentName(PACKAGE_NAME, "telComponentName"), "0", USER_HANDLE_16);
     private static final PhoneAccountHandle SIP_PA_HANDLE_17 = new PhoneAccountHandle(
-            new ComponentName("test", "sipComponentName"), "1", USER_HANDLE_17);
+            new ComponentName(PACKAGE_NAME, "sipComponentName"), "1", USER_HANDLE_17);
     private static final PhoneAccountHandle TEL_PA_HANDLE_CURRENT = new PhoneAccountHandle(
-            new ComponentName("test", "telComponentName"), "2", Binder.getCallingUserHandle());
+            new ComponentName(PACKAGE_NAME, "telComponentName"), "2",
+                    Binder.getCallingUserHandle());
     private static final PhoneAccountHandle SIP_PA_HANDLE_CURRENT = new PhoneAccountHandle(
-            new ComponentName("test", "sipComponentName"), "3", Binder.getCallingUserHandle());
-    private static final ComponentName THIRD_PARTY_CALL_SCREENING = new ComponentName("com.android" +
-            ".thirdparty", "com.android.thirdparty.callscreeningserviceimpl");
+            new ComponentName(PACKAGE_NAME, "sipComponentName"), "3",
+                    Binder.getCallingUserHandle());
+    private static final ComponentName THIRD_PARTY_CALL_SCREENING = new ComponentName(
+            "com.android.thirdparty", "com.android.thirdparty.callscreeningserviceimpl");
 
     @Override
     @Before
@@ -201,6 +204,7 @@
         when(mockTelephonyManager.isVoiceCapable()).thenReturn(true);
 
         doReturn(mContext).when(mContext).getApplicationContext();
+        doReturn(mContext).when(mContext).createContextAsUser(any(UserHandle.class), anyInt());
         doNothing().when(mContext).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class),
                 anyString());
         doAnswer(invocation -> {
@@ -458,12 +462,19 @@
 
     @SmallTest
     @Test
-    public void testGetPhoneAccount() throws RemoteException {
+    public void testGetPhoneAccount() throws Exception {
+        when(mPackageManager.getPackageUid(anyString(), eq(0))).thenReturn(Binder.getCallingUid());
         makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
         assertEquals(TEL_PA_HANDLE_16, mTSIBinder.getPhoneAccount(TEL_PA_HANDLE_16,
                 mContext.getPackageName()).getAccountHandle());
         assertEquals(SIP_PA_HANDLE_17, mTSIBinder.getPhoneAccount(SIP_PA_HANDLE_17,
                 mContext.getPackageName()).getAccountHandle());
+        try {
+            // Try to call the method without using the caller's package name
+            mTSIBinder.getPhoneAccount(TEL_PA_HANDLE_16, null);
+            fail("Should have thrown a SecurityException");
+        } catch (SecurityException expected) {
+        }
     }
 
     @SmallTest