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

Commit 10f20b6d authored by Tim Yu's avatar Tim Yu Committed by Automerger Merge Worker
Browse files

[DO NOT MERGE] Verify URI Permissions in Autofill RemoteViews am: ad7af765...

[DO NOT MERGE] Verify URI Permissions in Autofill RemoteViews am: ad7af765 am: 0bf40229 am: f4cfe454

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23772077



Change-Id: Ifa037e5fb7e78c976b497948881e122c4b300c59
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 0853289f f4cfe454
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static com.android.server.autofill.Helper.sDebug;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.app.assist.AssistStructure.WindowNode;
@@ -40,6 +42,7 @@ import android.view.View;
import android.view.WindowManager;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
import android.widget.RemoteViews;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;
@@ -50,6 +53,8 @@ import java.lang.ref.WeakReference;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;


public final class Helper {

@@ -83,6 +88,44 @@ public final class Helper {
        throw new UnsupportedOperationException("contains static members only");
    }

    private static boolean checkRemoteViewUriPermissions(
            @UserIdInt int userId, @NonNull RemoteViews rView) {
        final AtomicBoolean permissionsOk = new AtomicBoolean(true);

        rView.visitUris(uri -> {
            int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri);
            boolean allowed = uriOwnerId == userId;
            permissionsOk.set(allowed && permissionsOk.get());
        });

        return permissionsOk.get();
    }

    /**
     * Checks the URI permissions of the remote view,
     * to see if the current userId is able to access it.
     *
     * Returns the RemoteView that is passed if user is able, null otherwise.
     *
     * TODO: instead of returning a null remoteview when
     * the current userId cannot access an URI,
     * return a new RemoteView with the URI removed.
     */
    public static @Nullable RemoteViews sanitizeRemoteView(RemoteViews rView) {
        if (rView == null) return null;

        int userId = ActivityManager.getCurrentUser();

        boolean ok = checkRemoteViewUriPermissions(userId, rView);
        if (!ok) {
            Slog.w(TAG,
                    "sanitizeRemoteView() user: " + userId
                    + " tried accessing resource that does not belong to them");
        }
        return (ok ? rView : null);
    }


    @Nullable
    static AutofillId[] toArray(@Nullable ArraySet<AutofillId> set) {
        if (set == null) return null;
+8 −4
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.widget.TextView;

import com.android.internal.R;
import com.android.server.autofill.AutofillManagerService;
import com.android.server.autofill.Helper;

import java.io.PrintWriter;
import java.util.ArrayList;
@@ -208,7 +209,8 @@ final class DialogFillUi {
    }

    private void setHeader(View decor, FillResponse response) {
        final RemoteViews presentation = response.getDialogHeader();
        final RemoteViews presentation =
                Helper.sanitizeRemoteView(response.getDialogHeader());
        if (presentation == null) {
            return;
        }
@@ -243,9 +245,10 @@ final class DialogFillUi {
    }

    private void initialAuthenticationLayout(View decor, FillResponse response) {
        RemoteViews presentation = response.getDialogPresentation();
        RemoteViews presentation = Helper.sanitizeRemoteView(
                response.getDialogPresentation());
        if (presentation == null) {
            presentation = response.getPresentation();
            presentation = Helper.sanitizeRemoteView(response.getPresentation());
        }
        if (presentation == null) {
            throw new RuntimeException("No presentation for fill dialog authentication");
@@ -289,7 +292,8 @@ final class DialogFillUi {
            final Dataset dataset = response.getDatasets().get(i);
            final int index = dataset.getFieldIds().indexOf(focusedViewId);
            if (index >= 0) {
                RemoteViews presentation = dataset.getFieldDialogPresentation(index);
                RemoteViews presentation = Helper.sanitizeRemoteView(
                        dataset.getFieldDialogPresentation(index));
                if (presentation == null) {
                    if (sDebug) {
                        Slog.w(TAG, "not displaying UI on field " + focusedViewId + " because "
+8 −3
Original line number Diff line number Diff line
@@ -148,8 +148,9 @@ final class FillUi {

        final LayoutInflater inflater = LayoutInflater.from(mContext);

        final RemoteViews headerPresentation = response.getHeader();
        final RemoteViews footerPresentation = response.getFooter();
        final RemoteViews headerPresentation = Helper.sanitizeRemoteView(response.getHeader());
        final RemoteViews footerPresentation = Helper.sanitizeRemoteView(response.getFooter());

        final ViewGroup decor;
        if (mFullScreen) {
            decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_fullscreen, null);
@@ -227,6 +228,9 @@ final class FillUi {
            ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker);
            final View content;
            try {
                if (Helper.sanitizeRemoteView(response.getPresentation()) == null) {
                    throw new RuntimeException("Permission error accessing RemoteView");
                }
                content = response.getPresentation().applyWithTheme(
                        mContext, decor, interceptionHandler, mThemeId);
                container.addView(content);
@@ -306,7 +310,8 @@ final class FillUi {
                final Dataset dataset = response.getDatasets().get(i);
                final int index = dataset.getFieldIds().indexOf(focusedViewId);
                if (index >= 0) {
                    final RemoteViews presentation = dataset.getFieldPresentation(index);
                    final RemoteViews presentation = Helper.sanitizeRemoteView(
                            dataset.getFieldPresentation(index));
                    if (presentation == null) {
                        Slog.w(TAG, "not displaying UI on field " + focusedViewId + " because "
                                + "service didn't provide a presentation for it on " + dataset);
+1 −2
Original line number Diff line number Diff line
@@ -384,8 +384,7 @@ final class SaveUi {
            return false;
        }
        writeLog(MetricsEvent.AUTOFILL_SAVE_CUSTOM_DESCRIPTION);

        final RemoteViews template = customDescription.getPresentation();
        final RemoteViews template = Helper.sanitizeRemoteView(customDescription.getPresentation());
        if (template == null) {
            Slog.w(TAG, "No remote view on custom description");
            return false;