Loading core/java/android/app/IUriGrantsManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -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); } core/java/android/view/inputmethod/RemoteInputConnectionImpl.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 } Loading services/core/java/com/android/server/uri/UriGrantsManagerService.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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<>(); Loading Loading
core/java/android/app/IUriGrantsManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -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); }
core/java/android/view/inputmethod/RemoteInputConnectionImpl.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 } Loading
services/core/java/com/android/server/uri/UriGrantsManagerService.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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<>(); Loading