From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tim Yu <yunicorn@google.com>
Date: Tue, 12 Sep 2023 21:11:31 +0000
Subject: [PATCH] Check permission of Autofill icon URIs

* SaveUI's template
* Inline Suggestions slices

Fixes: b/286235483
Fixes: b/292104015

Test: atest CtsAutoFillServiceTestCases
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:91fb94942778c8907575a0eed674187dde854a5b)
Merged-In: I48879174664b70ced90492bb0991dc91cbf89b79
Change-Id: I48879174664b70ced90492bb0991dc91cbf89b79
---
 .../com/android/server/autofill/Helper.java   | 47 ++++++++++++++++++-
 .../android/server/autofill/ui/SaveUi.java    |  3 +-
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 8954a0c39091..123cadc9f6b4 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -23,7 +23,10 @@ import android.app.ActivityManager;
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
 import android.app.assist.AssistStructure.WindowNode;
+import android.app.slice.Slice;
+import android.app.slice.SliceItem;
 import android.content.ComponentName;
+import android.graphics.drawable.Icon;
 import android.metrics.LogMaker;
 import android.service.autofill.Dataset;
 import android.util.ArrayMap;
@@ -45,7 +48,6 @@ import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-
 public final class Helper {
 
     private static final String TAG = "AutofillHelper";
@@ -83,7 +85,7 @@ public final class Helper {
         final AtomicBoolean permissionsOk = new AtomicBoolean(true);
 
         rView.visitUris(uri -> {
-            int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri);
+            int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri, userId);
             boolean allowed = uriOwnerId == userId;
             permissionsOk.set(allowed && permissionsOk.get());
         });
@@ -115,6 +117,47 @@ public final class Helper {
         return (ok ? rView : null);
     }
 
+    /**
+     * Checks the URI permissions of the icon in the slice, to see if the current userId is able to
+     * access it.
+     *
+     * <p>Returns null if slice contains user inaccessible icons
+     *
+     * <p>TODO: instead of returning a null Slice when the current userId cannot access an icon,
+     * return a reconstructed Slice without the icons. This is currently non-trivial since there are
+     * no public methods to generically add SliceItems to Slices
+     */
+    public static @Nullable Slice sanitizeSlice(Slice slice) {
+        if (slice == null) {
+            return null;
+        }
+
+        int userId = ActivityManager.getCurrentUser();
+
+        // Recontruct the Slice, filtering out bad icons
+        for (SliceItem sliceItem : slice.getItems()) {
+            if (!sliceItem.getFormat().equals(SliceItem.FORMAT_IMAGE)) {
+                // Not an image slice
+                continue;
+            }
+
+            Icon icon = sliceItem.getIcon();
+            if (icon.getType() !=  Icon.TYPE_URI) {
+                // No URIs to sanitize
+                continue;
+            }
+
+            int iconUriId = android.content.ContentProvider.getUserIdFromUri(icon.getUri(), userId);
+
+            if (iconUriId != userId) {
+                Slog.w(TAG, "sanitizeSlice() user: " + userId + " cannot access icons in Slice");
+                return null;
+            }
+        }
+
+        return slice;
+    }
+
 
     @Nullable
     static AutofillId[] toArray(@Nullable ArraySet<AutofillId> set) {
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index aafd885e9bda..03d1c362c3c6 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -364,7 +364,8 @@ final class SaveUi {
                     }
                     final BatchUpdates batchUpdates = pair.second;
                     // First apply the updates...
-                    final RemoteViews templateUpdates = batchUpdates.getUpdates();
+                    final RemoteViews templateUpdates =
+                            Helper.sanitizeRemoteView(batchUpdates.getUpdates());
                     if (templateUpdates != null) {
                         if (sDebug) Slog.d(TAG, "Applying template updates for batch update #" + i);
                         templateUpdates.reapply(context, customSubtitleView);
