diff options
author | 2023-09-05 16:41:22 +0000 | |
---|---|---|
committer | 2023-09-05 16:41:22 +0000 | |
commit | 66bc218bbdebccd3a72207389fcb394f652a904e (patch) | |
tree | fc2c90d4a578454288b079d354234aa2f12f5f67 | |
parent | d66e274e3797b9a3c48da55a37073d3403f9164c (diff) | |
parent | 96ad0ecd45a36438b80a809ab4c669f5af8d9df1 (diff) |
Merge "Check originator IME Uri permissions" into main
3 files changed, 67 insertions, 0 deletions
diff --git a/core/java/android/app/IUriGrantsManager.aidl b/core/java/android/app/IUriGrantsManager.aidl index 9e7f2fecfea0..b630d034dca9 100644 --- a/core/java/android/app/IUriGrantsManager.aidl +++ b/core/java/android/app/IUriGrantsManager.aidl @@ -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); } diff --git a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java index f67a61be5879..61470f2bc71a 100644 --- a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java +++ b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java @@ -28,7 +28,13 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UiThread; +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 +43,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; @@ -1143,7 +1150,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 } diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java index 01fdc8800c0e..7862f58374a3 100644 --- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java +++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java @@ -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<>(); |