Skip to content

Commit 1dddc7f

Browse files
author
Nicolas Prevot
committed
Making getProviderMimeType work across users.
For apps with cross-user uri grants, but without INTERACT_ACROSS_USERS. BUG: 16128346 Change-Id: I0136cd274eaf457804d196c09f746f66c1fe599f
1 parent faa4b3c commit 1dddc7f

2 files changed

Lines changed: 29 additions & 10 deletions

File tree

core/java/android/content/ContentResolver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ public final String getType(Uri url) {
329329

330330
try {
331331
String type = ActivityManagerNative.getDefault().getProviderMimeType(
332-
url, UserHandle.myUserId());
332+
ContentProvider.getUriWithoutUserId(url), resolveUserId(url));
333333
return type;
334334
} catch (RemoteException e) {
335335
// Arbitrary and not worth documenting, as Activity

services/core/java/com/android/server/am/ActivityManagerService.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8971,8 +8971,10 @@ public final void installSystemProviders() {
89718971
}
89728972

89738973
/**
8974-
* Allows app to retrieve the MIME type of a URI without having permission
8975-
* to access its content provider.
8974+
* Allows apps to retrieve the MIME type of a URI.
8975+
* If an app is in the same user as the ContentProvider, or if it is allowed to interact across
8976+
* users, then it does not need permission to access the ContentProvider.
8977+
* Either, it needs cross-user uri grants.
89768978
*
89778979
* CTS tests for this functionality can be run with "runtest cts-appsecurity".
89788980
*
@@ -8981,12 +8983,22 @@ public final void installSystemProviders() {
89818983
*/
89828984
public String getProviderMimeType(Uri uri, int userId) {
89838985
enforceNotIsolatedCaller("getProviderMimeType");
8984-
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8985-
userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
89868986
final String name = uri.getAuthority();
8987-
final long ident = Binder.clearCallingIdentity();
8987+
int callingUid = Binder.getCallingUid();
8988+
int callingPid = Binder.getCallingPid();
8989+
long ident = 0;
8990+
boolean clearedIdentity = false;
8991+
userId = unsafeConvertIncomingUser(userId);
8992+
if (UserHandle.getUserId(callingUid) != userId) {
8993+
if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
8994+
callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
8995+
|| checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
8996+
callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
8997+
clearedIdentity = true;
8998+
ident = Binder.clearCallingIdentity();
8999+
}
9000+
}
89889001
ContentProviderHolder holder = null;
8989-
89909002
try {
89919003
holder = getContentProviderExternalUnchecked(name, null, userId);
89929004
if (holder != null) {
@@ -8996,10 +9008,17 @@ public String getProviderMimeType(Uri uri, int userId) {
89969008
Log.w(TAG, "Content provider dead retrieving " + uri, e);
89979009
return null;
89989010
} finally {
8999-
if (holder != null) {
9000-
removeContentProviderExternalUnchecked(name, null, userId);
9011+
// We need to clear the identity to call removeContentProviderExternalUnchecked
9012+
if (!clearedIdentity) {
9013+
ident = Binder.clearCallingIdentity();
9014+
}
9015+
try {
9016+
if (holder != null) {
9017+
removeContentProviderExternalUnchecked(name, null, userId);
9018+
}
9019+
} finally {
9020+
Binder.restoreCallingIdentity(ident);
90019021
}
9002-
Binder.restoreCallingIdentity(ident);
90039022
}
90049023

90059024
return null;

0 commit comments

Comments
 (0)