Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 846318a3 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Allow prefix-based Uri permission grants.

Define new FLAG_GRANT_PREFIX_URI_PERMISSION which indicates that a
Uri permission grant should also apply to any other Uris that have
matching scheme, authority, and path segments.  For example, a prefix
grant for /foo/ would allow /foo/bar/ but not /foo2/.

Allow persistable and prefix grants to be issued directly through
grantUriPermission().  Relaxing persistable is fine, since it still
requires the receiver to actively take the permission.

Since exact- and prefix-match grants for the same Uri can coexist,
we track them separately using a new UriGrant key.  (Consider the
case where an app separately extends READ|PREFIX and WRITE for
the same Uri: we can't let that become READ|WRITE|PREFIX.)

Fix revoke to always take away persisted permissions.  Move prefix
matching logic to Uri and add tests.  Add new flags to "am" tool, and
various internal uses around Intent and Context.  Switch some lagging
users to ArraySet.

Bug: 10607375
Change-Id: Ia8ce2b88421ff9f2fe5a979a27a026fc445d46f1
parent fb5d9f33
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -7075,6 +7075,7 @@ package android.content {
    field public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; // 0x10
    field public static final int FLAG_FROM_BACKGROUND = 4; // 0x4
    field public static final int FLAG_GRANT_PERSISTABLE_URI_PERMISSION = 64; // 0x40
    field public static final int FLAG_GRANT_PREFIX_URI_PERMISSION = 128; // 0x80
    field public static final int FLAG_GRANT_READ_URI_PERMISSION = 1; // 0x1
    field public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2; // 0x2
    field public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32; // 0x20
+5 −0
Original line number Diff line number Diff line
@@ -240,6 +240,7 @@ public class Am extends BaseCommand {
                "        (to embed a comma into a string escape it using \"\\,\")\n" +
                "    [-n <COMPONENT>] [-f <FLAGS>]\n" +
                "    [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
                "    [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]\n" +
                "    [--debug-log-resolution] [--exclude-stopped-packages]\n" +
                "    [--include-stopped-packages]\n" +
                "    [--activity-brought-to-front] [--activity-clear-top]\n" +
@@ -455,6 +456,10 @@ public class Am extends BaseCommand {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            } else if (opt.equals("--grant-write-uri-permission")) {
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            } else if (opt.equals("--grant-persistable-uri-permission")) {
                intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
            } else if (opt.equals("--grant-prefix-uri-permission")) {
                intent.addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
            } else if (opt.equals("--exclude-stopped-packages")) {
                intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
            } else if (opt.equals("--include-stopped-packages")) {
+19 −10
Original line number Diff line number Diff line
@@ -1865,17 +1865,26 @@ class ContextImpl extends Context {
    }

    private String uriModeFlagToString(int uriModeFlags) {
        switch (uriModeFlags) {
            case Intent.FLAG_GRANT_READ_URI_PERMISSION |
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
                return "read and write";
            case Intent.FLAG_GRANT_READ_URI_PERMISSION:
                return "read";
            case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
                return "write";
        StringBuilder builder = new StringBuilder();
        if ((uriModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
            builder.append("read and ");
        }
        if ((uriModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
            builder.append("write and ");
        }
        if ((uriModeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
            builder.append("persistable and ");
        }
        if ((uriModeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
            builder.append("prefix and ");
        }

        if (builder.length() > 5) {
            builder.setLength(builder.length() - 5);
            return builder.toString();
        } else {
            throw new IllegalArgumentException("Unknown permission mode flags: " + uriModeFlags);
        }
        throw new IllegalArgumentException(
                "Unknown permission mode flags: " + uriModeFlags);
    }

    private void enforceForUri(
+2 −2
Original line number Diff line number Diff line
@@ -1641,7 +1641,7 @@ public abstract class ContentResolver {
     *
     * @see #getPersistedUriPermissions()
     */
    public void takePersistableUriPermission(Uri uri, int modeFlags) {
    public void takePersistableUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags) {
        try {
            ActivityManagerNative.getDefault().takePersistableUriPermission(uri, modeFlags);
        } catch (RemoteException e) {
@@ -1656,7 +1656,7 @@ public abstract class ContentResolver {
     *
     * @see #getPersistedUriPermissions()
     */
    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
    public void releasePersistableUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags) {
        try {
            ActivityManagerNative.getDefault().releasePersistableUriPermission(uri, modeFlags);
        } catch (RemoteException e) {
+17 −12
Original line number Diff line number Diff line
@@ -2791,9 +2791,13 @@ public abstract class Context {
     * @param uri The Uri you would like to grant access to.
     * @param modeFlags The desired access modes.  Any combination of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
     * Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * Intent.FLAG_GRANT_READ_URI_PERMISSION},
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
     * Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     * Intent.FLAG_GRANT_WRITE_URI_PERMISSION},
     * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION
     * Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION}, or
     * {@link Intent#FLAG_GRANT_PREFIX_URI_PERMISSION
     * Intent.FLAG_GRANT_PREFIX_URI_PERMISSION}.
     *
     * @see #revokeUriPermission
     */
@@ -2806,7 +2810,8 @@ public abstract class Context {
     * Uri will match all previously granted Uris that are the same or a
     * sub-path of the given Uri.  That is, revoking "content://foo/target" will
     * revoke both "content://foo/target" and "content://foo/target/sub", but not
     * "content://foo".
     * "content://foo".  It will not remove any prefix grants that exist at a
     * higher level.
     *
     * @param uri The Uri you would like to revoke access to.
     * @param modeFlags The desired access modes.  Any combination of
@@ -2817,7 +2822,7 @@ public abstract class Context {
     *
     * @see #grantUriPermission
     */
    public abstract void revokeUriPermission(Uri uri, @Intent.GrantUriMode int modeFlags);
    public abstract void revokeUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether a particular process and user ID has been granted
@@ -2841,7 +2846,7 @@ public abstract class Context {
     * @see #checkCallingUriPermission
     */
    public abstract int checkUriPermission(Uri uri, int pid, int uid,
            @Intent.GrantUriMode int modeFlags);
            @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether the calling process and user ID has been
@@ -2864,7 +2869,7 @@ public abstract class Context {
     *
     * @see #checkUriPermission(Uri, int, int, int)
     */
    public abstract int checkCallingUriPermission(Uri uri, @Intent.GrantUriMode int modeFlags);
    public abstract int checkCallingUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether the calling process of an IPC <em>or you</em> has been granted
@@ -2884,7 +2889,7 @@ public abstract class Context {
     * @see #checkCallingUriPermission
     */
    public abstract int checkCallingOrSelfUriPermission(Uri uri,
            @Intent.GrantUriMode int modeFlags);
            @Intent.AccessUriMode int modeFlags);

    /**
     * Check both a Uri and normal permission.  This allows you to perform
@@ -2910,7 +2915,7 @@ public abstract class Context {
     */
    public abstract int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission,
            @Nullable String writePermission, int pid, int uid,
            @Intent.GrantUriMode int modeFlags);
            @Intent.AccessUriMode int modeFlags);

    /**
     * If a particular process and user ID has not been granted
@@ -2932,7 +2937,7 @@ public abstract class Context {
     * @see #checkUriPermission(Uri, int, int, int)
     */
    public abstract void enforceUriPermission(
            Uri uri, int pid, int uid, @Intent.GrantUriMode int modeFlags, String message);
            Uri uri, int pid, int uid, @Intent.AccessUriMode int modeFlags, String message);

    /**
     * If the calling process and user ID has not been granted
@@ -2954,7 +2959,7 @@ public abstract class Context {
     * @see #checkCallingUriPermission(Uri, int)
     */
    public abstract void enforceCallingUriPermission(
            Uri uri, @Intent.GrantUriMode int modeFlags, String message);
            Uri uri, @Intent.AccessUriMode int modeFlags, String message);

    /**
     * If the calling process of an IPC <em>or you</em> has not been
@@ -2973,7 +2978,7 @@ public abstract class Context {
     * @see #checkCallingOrSelfUriPermission(Uri, int)
     */
    public abstract void enforceCallingOrSelfUriPermission(
            Uri uri, @Intent.GrantUriMode int modeFlags, String message);
            Uri uri, @Intent.AccessUriMode int modeFlags, String message);

    /**
     * Enforce both a Uri and normal permission.  This allows you to perform
@@ -2998,7 +3003,7 @@ public abstract class Context {
     */
    public abstract void enforceUriPermission(
            @Nullable Uri uri, @Nullable String readPermission,
            @Nullable String writePermission, int pid, int uid, @Intent.GrantUriMode int modeFlags,
            @Nullable String writePermission, int pid, int uid, @Intent.AccessUriMode int modeFlags,
            @Nullable String message);

    /** @hide */
Loading