Skip to content
Snippets Groups Projects
Commit 9b03491b authored by Tim Yu's avatar Tim Yu
Browse files

[RESTRICT AUTOMERGE] Check permission of Autofill icon URIs

* SaveUI's template
* Inline Suggestions slices

Fixes: b/286235483
Fixes: b/292104015

Test: atest CtsAutoFillServiceTestCases

Change-Id: I48879174664b70ced90492bb0991dc91cbf89b79
Merged-In: I48879174664b70ced90492bb0991dc91cbf89b79
parent ccc748a0
No related branches found
No related tags found
No related merge requests found
......@@ -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,48 @@ 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
&& icon.getType() != Icon.TYPE_URI_ADAPTIVE_BITMAP) {
// 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) {
......
......@@ -27,6 +27,7 @@ import android.service.autofill.InlinePresentation;
import android.util.Slog;
import com.android.server.LocalServices;
import com.android.server.autofill.Helper;
import com.android.server.autofill.RemoteInlineSuggestionRenderService;
import com.android.server.inputmethod.InputMethodManagerInternal;
......@@ -39,12 +40,9 @@ import java.util.function.Consumer;
final class RemoteInlineSuggestionViewConnector {
private static final String TAG = RemoteInlineSuggestionViewConnector.class.getSimpleName();
@Nullable
private final RemoteInlineSuggestionRenderService mRemoteRenderService;
@NonNull
private final InlinePresentation mInlinePresentation;
@Nullable
private final IBinder mHostInputToken;
@Nullable private final RemoteInlineSuggestionRenderService mRemoteRenderService;
@NonNull private final InlinePresentation mInlinePresentation;
@Nullable private final IBinder mHostInputToken;
private final int mDisplayId;
private final int mUserId;
private final int mSessionId;
......@@ -82,8 +80,12 @@ final class RemoteInlineSuggestionViewConnector {
*
* @return true if the call is made to the remote renderer service, false otherwise.
*/
public boolean renderSuggestion(int width, int height,
@NonNull IInlineSuggestionUiCallback callback) {
public boolean renderSuggestion(
int width, int height, @NonNull IInlineSuggestionUiCallback callback) {
if (Helper.sanitizeSlice(mInlinePresentation.getSlice()) == null) {
if (sDebug) Slog.d(TAG, "Skipped rendering inline suggestion.");
return false;
}
if (mRemoteRenderService != null) {
if (sDebug) Slog.d(TAG, "Request to recreate the UI");
mRemoteRenderService.renderSuggestion(callback, mInlinePresentation, width, height,
......
......@@ -418,7 +418,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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment