Migrates to the new resolveContentProvider api

The original resolveContentProvider api gets the caller's uid using
the Binder#getCallingUid. That may cause the package information
disclosure issue if the caller has cleared the calling identify.
This cl migrates the callers of resolveContentProvider to use the
new one with a calling uid parameter. The caller could pass the
correct caller's uid to use the api.

Bug: 192354703
Test: atest UriGrantsManagerServiceTest
Test: atest UriPermissionTest
Test: atest ContextTest
Change-Id: I153df4e77642f0622c7f0f5804639795e90ded21
This commit is contained in:
Rhed Jao
2021-07-23 14:58:04 +08:00
parent a549d4656e
commit 80573612b2
6 changed files with 21 additions and 37 deletions

View File

@@ -561,11 +561,6 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP
public abstract ResolveInfo resolveService(Intent intent, String resolvedType,
int flags, int userId, int callingUid);
/**
* Resolves a content provider intent.
*/
public abstract ProviderInfo resolveContentProvider(String name, int flags, int userId);
/**
* Resolves a content provider intent.
*/

View File

@@ -1032,7 +1032,7 @@ class StorageManagerService extends IStorageManager.Stub
final ProviderInfo provider = mPmInternal.resolveContentProvider(
MediaStore.AUTHORITY, PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
user.id);
user.id, Process.SYSTEM_UID);
if (provider != null) {
final IActivityManager am = ActivityManager.getService();
try {
@@ -2021,7 +2021,7 @@ class StorageManagerService extends IStorageManager.Stub
return mPmInternal.resolveContentProvider(
authority, PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.getUserId(UserHandle.USER_SYSTEM));
UserHandle.getUserId(UserHandle.USER_SYSTEM), Process.SYSTEM_UID);
}
private void updateLegacyStorageApps(String packageName, int uid, boolean hasLegacy) {

View File

@@ -11651,14 +11651,6 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
return resolveContentProviderInternal(name, flags, userId);
}
public ProviderInfo resolveContentProvider(String name, int flags, int userId, int callingUid) {
return resolveContentProviderInternal(name, flags, userId, callingUid);
}
private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
return resolveContentProviderInternal(name, flags, userId, Binder.getCallingUid());
}
@@ -27829,12 +27821,6 @@ public class PackageManagerService extends IPackageManager.Stub
return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
}
@Override
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
return PackageManagerService.this.resolveContentProviderInternal(
name, flags, userId);
}
@Override
public ProviderInfo resolveContentProvider(String name, int flags, int userId,
int callingUid) {
@@ -28616,8 +28602,8 @@ public class PackageManagerService extends IPackageManager.Stub
public void grantImplicitAccess(int recipientUid, String visibleAuthority) {
// This API is exposed temporarily to only the contacts provider. (b/158688602)
final int callingUid = Binder.getCallingUid();
ProviderInfo contactsProvider = resolveContentProviderInternal(
ContactsContract.AUTHORITY, 0, UserHandle.getUserId(callingUid));
ProviderInfo contactsProvider = resolveContentProviderInternal(ContactsContract.AUTHORITY,
0, UserHandle.getUserId(callingUid), callingUid);
if (contactsProvider == null || contactsProvider.applicationInfo == null
|| !UserHandle.isSameApp(contactsProvider.applicationInfo.uid, callingUid)) {
throw new SecurityException(callingUid + " is not allow to call grantImplicitAccess");

View File

@@ -695,7 +695,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
// Both direct boot aware and unaware packages are fine as we
// will do filtering at query time to avoid multiple parsing.
final ProviderInfo pi = getProviderInfo(uri.getAuthority(), sourceUserId,
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, SYSTEM_UID);
if (pi != null && sourcePkg.equals(pi.packageName)) {
int targetUid = mPmInternal.getPackageUid(
targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
@@ -759,9 +759,10 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
if (DEBUG) Slog.v(TAG,
"Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
// Unchecked call, passing the system's uid as the calling uid to the getProviderInfo
final String authority = grantUri.uri.getAuthority();
final ProviderInfo pi = getProviderInfo(authority, grantUri.sourceUserId,
MATCH_DEBUG_TRIAGED_MISSING);
MATCH_DEBUG_TRIAGED_MISSING, SYSTEM_UID);
if (pi == null) {
Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
return;
@@ -812,7 +813,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
final String authority = grantUri.uri.getAuthority();
final ProviderInfo pi = getProviderInfo(authority, grantUri.sourceUserId,
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUid);
if (pi == null) {
Slog.w(TAG, "No content provider found for permission revoke: "
+ grantUri.toSafeString());
@@ -1056,11 +1057,6 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
}
}
private ProviderInfo getProviderInfo(String authority, int userHandle, int pmFlags) {
return mPmInternal.resolveContentProvider(authority,
PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags, userHandle);
}
private ProviderInfo getProviderInfo(String authority, int userHandle, int pmFlags,
int callingUid) {
return mPmInternal.resolveContentProvider(authority,

View File

@@ -55,6 +55,7 @@ import android.content.ClipData;
import android.content.Intent;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Process;
import android.os.UserHandle;
import android.util.ArraySet;
@@ -356,7 +357,7 @@ public class UriGrantsManagerServiceTest {
final UriPermissionOwner owner = new UriPermissionOwner(mService, "primary");
final ProviderInfo cameraInfo = mContext.mPmInternal.resolveContentProvider(
PKG_CAMERA, 0, USER_PRIMARY);
PKG_CAMERA, 0, USER_PRIMARY, Process.SYSTEM_UID);
// By default no social can see any camera
assertFalse(mService.checkAuthorityGrants(UID_PRIMARY_SOCIAL,

View File

@@ -35,6 +35,7 @@ import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.FileUtils;
import android.os.PatternMatcher;
import android.os.Process;
import android.os.UserHandle;
import android.test.mock.MockContentResolver;
import android.test.mock.MockPackageManager;
@@ -133,27 +134,32 @@ public class UriGrantsMockContext extends ContextWrapper {
when(mPmInternal.getPackageUid(eq(PKG_COMPLEX), anyInt(), eq(userId)))
.thenReturn(UserHandle.getUid(userId, UID_COMPLEX));
when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyInt(), eq(userId)))
when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyInt(), eq(userId),
eq(Process.SYSTEM_UID)))
.thenReturn(buildCameraProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyInt(), eq(userId),
eq(UserHandle.getUid(userId, UID_CAMERA))))
.thenReturn(buildCameraProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyInt(), eq(userId)))
when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyInt(), eq(userId),
eq(Process.SYSTEM_UID)))
.thenReturn(buildPrivateProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyInt(), eq(userId),
eq(UserHandle.getUid(userId, UID_PRIVATE))))
.thenReturn(buildPrivateProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyInt(), eq(userId)))
when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyInt(), eq(userId),
eq(Process.SYSTEM_UID)))
.thenReturn(buildPublicProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyInt(), eq(userId),
eq(UserHandle.getUid(userId, UID_PUBLIC))))
.thenReturn(buildPublicProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyInt(), eq(userId)))
when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyInt(), eq(userId),
eq(Process.SYSTEM_UID)))
.thenReturn(buildForceProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyInt(), eq(userId),
eq(UserHandle.getUid(userId, UID_FORCE))))
.thenReturn(buildForceProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyInt(), eq(userId)))
when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyInt(), eq(userId),
eq(Process.SYSTEM_UID)))
.thenReturn(buildComplexProvider(userId));
when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyInt(), eq(userId),
eq(UserHandle.getUid(userId, UID_COMPLEX))))