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:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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))))
|
||||
|
||||
Reference in New Issue
Block a user