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

Commit a537f11f authored by Iavor-Valentin Iftime's avatar Iavor-Valentin Iftime Committed by Automerger Merge Worker
Browse files

Merge "Check originator IME Uri permissions" into udc-qpr-dev am: dead0f9c

parents 2067984f dead0f9c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -39,4 +39,7 @@ interface IUriGrantsManager {
    void clearGrantedUriPermissions(in String packageName, int userId);
    ParceledListSlice getUriPermissions(in String packageName, boolean incoming,
            boolean persistedOnly);

    int checkGrantUriPermission_ignoreNonSystem(
            int sourceUid, String targetPkg, in Uri uri, int modeFlags, int userId);
}
+21 −0
Original line number Diff line number Diff line
@@ -28,7 +28,12 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.UriGrantsManager;
import android.content.ContentProvider;
import android.content.Intent;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.CancellationSignalBeamer;
@@ -37,6 +42,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.ResultReceiver;
import android.os.Trace;
import android.os.UserHandle;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.view.KeyEvent;
@@ -1193,7 +1199,22 @@ final class RemoteInputConnectionImpl extends IRemoteInputConnection.Stub {
    public void commitContent(InputConnectionCommandHeader header,
            InputContentInfo inputContentInfo, int flags, Bundle opts,
            AndroidFuture future /* T=Boolean */) {
        final int imeUid = Binder.getCallingUid();
        dispatchWithTracing("commitContent", future, () -> {
            // Check if the originator IME has the right permissions
            try {
                final int contentUriOwnerUserId = ContentProvider.getUserIdFromUri(
                        inputContentInfo.getContentUri(), UserHandle.getUserId(imeUid));
                final Uri contentUriWithoutUserId = ContentProvider.getUriWithoutUserId(
                        inputContentInfo.getContentUri());
                UriGrantsManager.getService().checkGrantUriPermission_ignoreNonSystem(imeUid, null,
                        contentUriWithoutUserId, Intent.FLAG_GRANT_READ_URI_PERMISSION,
                        contentUriOwnerUserId);
            } catch (Exception e) {
                Log.w(TAG, "commitContent with invalid Uri permission from IME:", e);
                return false;
            }

            if (header.mSessionId != mCurrentSessionId.get()) {
                return false;  // cancelled
            }
+42 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
@@ -62,6 +63,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -1304,6 +1306,46 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
        return false;
    }

    /**
     * Check if the targetPkg can be granted permission to access uri by
     * the callingUid using the given modeFlags. See {@link #checkGrantUriPermissionUnlocked}.
     *
     * @param callingUid The uid of the grantor app that has permissions to the uri.
     * @param targetPkg The package name of the granted app that needs permissions to the uri.
     * @param uri The uri for which permissions should be granted.
     * @param modeFlags The modes to grant. See {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}, etc.
     * @param userId The userId in which the uri is to be resolved.
     * @return uid of the target or -1 if permission grant not required. Returns -1 if the caller
     *  does not hold INTERACT_ACROSS_USERS_FULL
     * @throws SecurityException if the grant is not allowed.
     */
    @Override
    @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
    public int checkGrantUriPermission_ignoreNonSystem(int callingUid, String targetPkg, Uri uri,
            int modeFlags, int userId) {
        if (!isCallerIsSystemOrPrivileged()) {
            return Process.INVALID_UID;
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            return checkGrantUriPermissionUnlocked(callingUid, targetPkg, uri, modeFlags,
                        userId);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    private boolean isCallerIsSystemOrPrivileged() {
        final int uid = Binder.getCallingUid();
        if (uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) {
            return true;
        }
        return ActivityManager.checkComponentPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    uid, /* owningUid = */-1, /* exported = */ true)
                    == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public ArrayList<UriPermission> providePersistentUriGrants() {
        final ArrayList<UriPermission> result = new ArrayList<>();