From 192679a7d37d268854f4b17876c702625f9475eb Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 10 Sep 2014 14:28:48 -0700 Subject: [PATCH] Fix issue #17428001: Fix revokeUriPermissions You can now revoke permissions that were granted to you. Change-Id: I9a1872059edc715b10bbd2d653e45420d43331c3 --- core/java/android/content/Context.java | 8 +++++ .../server/am/ActivityManagerService.java | 33 +++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index f979a0c585828..61dd7476aae03 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3062,6 +3062,14 @@ public abstract class Context { * "content://foo". It will not remove any prefix grants that exist at a * higher level. * + *

Prior to {@link android.os.Build.VERSION_CODES#L}, if you did not have + * regular permission access to a Uri, but had received access to it through + * a specific Uri permission grant, you could not revoke that grant with this + * function and a {@link SecurityException} would be thrown. As of + * {@link android.os.Build.VERSION_CODES#L}, this function will not throw a security exception, + * but will remove whatever permission grants to the Uri had been given to the app + * (or none).

+ * * @param uri The Uri you would like to revoke access to. * @param modeFlags The desired access modes. Any combination of * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a9a47327ead66..22db6f35ac308 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7446,12 +7446,33 @@ public final class ActivityManagerService extends ActivityManagerNative // Does the caller have this permission on the URI? if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { - // Right now, if you are not the original owner of the permission, - // you are not allowed to revoke it. - //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { - throw new SecurityException("Uid " + callingUid - + " does not have permission to uri " + grantUri); - //} + // Have they don't have direct access to the URI, then revoke any URI + // permissions that have been granted to them. + final ArrayMap perms = mGrantedUriPermissions.get(callingUid); + if (perms != null) { + boolean persistChanged = false; + for (Iterator it = perms.values().iterator(); it.hasNext();) { + final UriPermission perm = it.next(); + if (perm.uri.sourceUserId == grantUri.sourceUserId + && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { + if (DEBUG_URI_PERMISSION) + Slog.v(TAG, + "Revoking " + perm.targetUid + " permission to " + perm.uri); + persistChanged |= perm.revokeModes( + modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + if (perm.modeFlags == 0) { + it.remove(); + } + } + } + if (perms.isEmpty()) { + mGrantedUriPermissions.remove(callingUid); + } + if (persistChanged) { + schedulePersistUriGrants(); + } + } + return; } boolean persistChanged = false;