diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java index 8a03431f99..b5ac4ff25b 100644 --- a/src/java/com/android/internal/telephony/SubscriptionController.java +++ b/src/java/com/android/internal/telephony/SubscriptionController.java @@ -875,6 +875,19 @@ public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex, @Override public List getAllSubInfoList(String callingPackage, String callingFeatureId) { + return getAllSubInfoList(callingPackage, callingFeatureId, false); + } + + /** + * @param callingPackage The package making the IPC. + * @param callingFeatureId The feature in the package + * @param skipConditionallyRemoveIdentifier if set, skip removing identifier conditionally + * @return List of all SubscriptionInfo records in database, + * include those that were inserted before, maybe empty but not null. + * @hide + */ + public List getAllSubInfoList(String callingPackage, + String callingFeatureId, boolean skipConditionallyRemoveIdentifier) { if (VDBG) logd("[getAllSubInfoList]+"); // This API isn't public, so no need to provide a valid subscription ID - we're not worried @@ -887,24 +900,24 @@ public List getAllSubInfoList(String callingPackage, // Now that all security checks passes, perform the operation as ourselves. final long identity = Binder.clearCallingIdentity(); + List subList; try { - List subList = null; subList = getSubInfo(null, null); - if (subList != null) { - if (VDBG) logd("[getAllSubInfoList]- " + subList.size() + " infos return"); - subList.stream().map( - subscriptionInfo -> conditionallyRemoveIdentifiers(subscriptionInfo, - callingPackage, callingFeatureId, "getAllSubInfoList")) - .collect(Collectors.toList()); - } else { - if (VDBG) logd("[getAllSubInfoList]- no info return"); - } - return subList; } finally { Binder.restoreCallingIdentity(identity); } + if (subList != null && !skipConditionallyRemoveIdentifier) { + if (VDBG) logd("[getAllSubInfoList]- " + subList.size() + " infos return"); + subList = subList.stream().map( + subscriptionInfo -> conditionallyRemoveIdentifiers(subscriptionInfo, + callingPackage, callingFeatureId, "getAllSubInfoList")) + .collect(Collectors.toList()); + } else { + if (VDBG) logd("[getAllSubInfoList]- no info return"); + } + return subList; } - + private List makeCacheListCopyWithLock(List cacheSubList) { synchronized (mSubInfoListLock) { return new ArrayList<>(cacheSubList); @@ -3016,9 +3029,19 @@ private int setSubscriptionPropertyIntoContentResolver( @Override public String getSubscriptionProperty(int subId, String propKey, String callingPackage, String callingFeatureId) { - if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage, - callingFeatureId, "getSubscriptionProperty")) { - return null; + switch (propKey) { + case SubscriptionManager.GROUP_UUID: + if (mContext.checkCallingOrSelfPermission( + Manifest.permission.READ_PRIVILEGED_PHONE_STATE) != PERMISSION_GRANTED) { + EventLog.writeEvent(0x534e4554, "213457638", Binder.getCallingUid()); + return null; + } + break; + default: + if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, + callingPackage, callingFeatureId, "getSubscriptionProperty")) { + return null; + } } final long identity = Binder.clearCallingIdentity(); @@ -3687,8 +3710,10 @@ public List getSubscriptionsInGroup(ParcelUuid groupUuid, List subInfoList; try { + // need to bypass removing identifier check because that will remove the subList without + // group id. subInfoList = getAllSubInfoList(mContext.getOpPackageName(), - mContext.getAttributionTag()); + mContext.getAttributionTag(), true); if (groupUuid == null || subInfoList == null || subInfoList.isEmpty()) { return new ArrayList<>(); } @@ -4371,4 +4396,4 @@ public static void disableCaching() { public static void enableCaching() { sCachingEnabled = true; } -} +} \ No newline at end of file diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java index 4d10b0a71f..aeb0c8bf33 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java @@ -951,6 +951,37 @@ public void testSetSubscriptionGroupWithModifyPermission() throws Exception { assertNotEquals(groupId, newGroupId); } + @Test + @SmallTest + public void testGetSubscriptionProperty() throws Exception { + testInsertSim(); + ContentValues values = new ContentValues(); + values.put(SubscriptionManager.GROUP_UUID, 1); + mFakeTelephonyProvider.update(SubscriptionManager.CONTENT_URI, values, + SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 1, null); + + mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL); + mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE); + + // should succeed with read phone state permission + String prop = mSubscriptionControllerUT.getSubscriptionProperty(1, + SubscriptionManager.CB_EXTREME_THREAT_ALERT, mContext.getOpPackageName(), + mContext.getAttributionTag()); + + assertNotEquals(null, prop); + + // group UUID requires privileged phone state permission + prop = mSubscriptionControllerUT.getSubscriptionProperty(1, SubscriptionManager.GROUP_UUID, + mContext.getOpPackageName(), mContext.getAttributionTag()); + assertEquals(null, prop); + + // group UUID should succeed once privileged phone state permission is granted + mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); + prop = mSubscriptionControllerUT.getSubscriptionProperty(1, SubscriptionManager.GROUP_UUID, + mContext.getOpPackageName(), mContext.getAttributionTag()); + assertNotEquals(null, prop); + } + @Test @SmallTest public void testCreateSubscriptionGroupWithCarrierPrivilegePermission() throws Exception {