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

Commit ce300740 authored by Abhijeet Kaur's avatar Abhijeet Kaur
Browse files

Fix getUserIdFromUri() call for checkUriPermissions

checkUriPermissions is an API to check Uri permissions on a list of
Uris. This is an optimisation over calling checkUriPermission separately
for each Uri in the list as each call is a binder call.

The bug is caused due to getContext.checkUriPermissions() for User 10
calling into ActivityManagerService(AMS) for User 0. The old APIs
(checkUriPermission for 1 Uri) resolves the user one step before
calling into AMS that is in ContextImpl class. But resolving the
calling user via context in AMS is not resolving the actual user (in
this case the calling user is user 10, and AMS context resolves the
userId to User 0).
Resolving the user in AMS was a conscious decision we made as we wanted
to resolve the user for each uri in the list separately.

Fixed the above issue by passing userId to AMS from ContextImpl and then
resolving the user for each uri.

Bug: 194700183
Test: atest --user-type secondary_user CtsScopedStorageDeviceOnlyTest:android.scopedstorage.cts.device.RedactUriDeviceTest#testSharedRedactedUri_openFileForRead -c
Change-Id: Ia4f0ba39a34c8ae4bd46d6f10bca1052f1331400
parent c987118c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AttributionSource;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -60,7 +61,6 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.content.AttributionSource;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -2260,7 +2260,7 @@ class ContextImpl extends Context {
            int modeFlags) {
        try {
            return ActivityManager.getService().checkUriPermissions(uris, pid, uid, modeFlags,
                    null);
                    getUserId(), null);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+1 −1
Original line number Diff line number Diff line
@@ -221,7 +221,7 @@ interface IActivityManager {
    int getProcessLimit();
    int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
            in IBinder callerToken);
    int[] checkUriPermissions(in List<Uri> uris, int pid, int uid, int mode,
    int[] checkUriPermissions(in List<Uri> uris, int pid, int uid, int mode, int userId,
                in IBinder callerToken);
    void grantUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
            int mode, int userId);
+3 −3
Original line number Diff line number Diff line
@@ -5696,7 +5696,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
            final int modeFlags, IBinder callerToken) {
            final int modeFlags, int userId, IBinder callerToken) {
        final int size = uris.size();
        int[] res = new int[size];
        // Default value DENIED.
@@ -5704,9 +5704,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        for (int i = 0; i < size; i++) {
            final Uri uri = uris.get(i);
            final int userId = ContentProvider.getUserIdFromUri(uri, mContext.getUserId());
            final int userIdFromUri = ContentProvider.getUserIdFromUri(uri, userId);
            res[i] = checkUriPermission(ContentProvider.getUriWithoutUserId(uri), pid, uid,
                    modeFlags, userId, callerToken);
                    modeFlags, userIdFromUri, callerToken);
        }
        return res;
    }