CVE-2024-0037 AI-generated analysis
platform/frameworks/base, system_server Autofill service (services/autofill: Helper, SaveUi, RemoteInlineSuggestionViewConnector)
Adds cross-user URI ownership checks to Autofill UI content supplied by the autofill service. A new Helper.sanitizeSlice() gates inline suggestion rendering in RemoteInlineSuggestionViewConnector.renderSuggestion. SaveUi now passes CustomDescription BatchUpdates RemoteViews through Helper.sanitizeRemoteView. sanitizeRemoteView now resolves URIs that carry no explicit user against the checked userId.
Root cause
Two autofill UI paths rendered service-supplied content without checking which user owns the embedded content URIs. (1) SaveUi.applyCustomDescription applied batchUpdates.getUpdates() RemoteViews directly via reapply(), without the pre-existing Helper.sanitizeRemoteView URI check. (2) RemoteInlineSuggestionViewConnector.renderSuggestion forwarded the InlinePresentation Slice to the remote render service without inspecting the Icon URIs (TYPE_URI / TYPE_URI_ADAPTIVE_BITMAP) in its SliceItems. In addition, sanitizeRemoteView used the one-argument ContentProvider.getUserIdFromUri(uri), so URIs without an explicit user component were not resolved against the userId being checked.
How the fix works
- services/autofill/java/com/android/server/autofill/Helper.java: sanitizeRemoteView now calls ContentProvider.getUserIdFromUri(uri, userId) inside the rView.visitUris lambda, so a URI without an explicit user id defaults to the user being checked. The one-argument overload defaults to UserHandle.USER_CURRENT (general platform knowledge).
- Helper.java: new public static @Nullable Slice sanitizeSlice(Slice slice). It returns null for a null slice and takes userId = ActivityManager.getCurrentUser(). It iterates slice.getItems(), skips items whose format is not SliceItem.FORMAT_IMAGE, and skips Icons whose type is neither Icon.TYPE_URI nor Icon.TYPE_URI_ADAPTIVE_BITMAP. For the remaining icons it computes ContentProvider.getUserIdFromUri(icon.getUri(), userId). If that differs from userId, it logs a warning and returns null, which rejects the whole slice. Otherwise it returns the slice unchanged.
- services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java: renderSuggestion(int width, int height, IInlineSuggestionUiCallback callback) now calls Helper.sanitizeSlice(mInlinePresentation.getSlice()) first. If the result is null, it logs (debug) and returns false before any call to mRemoteRenderService.renderSuggestion. The rest of the hunk only reformats annotations.
- services/autofill/java/com/android/server/autofill/ui/SaveUi.java: in the batch-update loop of applyCustomDescription, templateUpdates is now Helper.sanitizeRemoteView(batchUpdates.getUpdates()) instead of batchUpdates.getUpdates(). The existing null check follows, so a RemoteViews that fails the URI ownership check is not reapplied to customSubtitleView.
Completeness
- sanitizeSlice only inspects the top-level slice.getItems(). It does not recurse into nested items, and it only checks FORMAT_IMAGE icons of URI types. Other URI carriers in the Slice are not examined.
- sanitizeSlice rejects the whole Slice (returns null) instead of filtering out the offending icons. A TODO in the code acknowledges this.
- sanitizeSlice compares against ActivityManager.getCurrentUser(), not the connector's mUserId field.
- In SaveUi only batchUpdates.getUpdates() is wrapped. This commit does not change the batch transformations path (InternalTransformation.batchApply followed by template.reapply) or the initial template.applyWithTheme call. The material does not show whether the template itself is sanitized earlier.
- The default-user change is inside sanitizeRemoteView, so it applies to every caller of that function, not only the new SaveUi call site.
Behavior changes
- Inline suggestions whose InlinePresentation Slice contains an image Icon URI owned by a different user are no longer rendered. renderSuggestion returns false without contacting the render service and logs a Slog.w 'sanitizeSlice() user: N cannot access icons in Slice'.
- SaveUI CustomDescription batch-update RemoteViews that contain URIs owned by another user are skipped (not reapplied).
- In sanitizeRemoteView, URIs with no explicit user component are now attributed to the checked userId, which can change which RemoteViews pass the check.
Per major
- Android 14: same fix: platform/frameworks/base 55fc00a0788e in android-security-14.0.0_r5 ([RESTRICT AUTOMERGE], cherry-picked from df893defcf8c, Change-Id I48879174664b70ced90492bb0991dc91cbf89b79). It touches Helper.java, RemoteInlineSuggestionViewConnector.java and SaveUi.java. At android-security-14.0.0_r29, 8/8 lines of the patched region are present, and SaveUi shows Helper.sanitizeRemoteView(batchUpdates.getUpdates()).
- Android 15: adapted fix: platform/frameworks/base 2d1d69e1571c in android-security-15.0.0_r5. The diff shown contains the Helper.java and RemoteInlineSuggestionViewConnector.java hunks; its sanitizeRemoteView context has '&' where 14 has '&&'. The material does not show a SaveUi.java hunk. At android-security-15.0.0_r17, 8/8 lines of the patched region are present.
- Android 16: not affected (not listed by the bulletin). At android-security-16.0.0_r8, 8/8 lines of the patched region are present.
- Android 17: not affected (not listed by the bulletin). At android-security-17.0.0_r1, 8/8 lines of the patched region are present.
Unknowns
- Whether the SaveUi.java change was already present on Android 15 before 2d1d69e1571c or landed separately; the 15 diff shown omits that file.
- Whether the SaveUi template passed to applyWithTheme and the transformation path are sanitized elsewhere.
- Which other callers sanitizeRemoteView has.
- Whether ActivityManager.getCurrentUser() and the connector's mUserId can differ in a way that matters for this check.
- What triggers RemoteInlineSuggestionViewConnector.renderSuggestion.
- Which of the two bugs (b/286235483, b/292104015) corresponds to which code path.
- The CTS test changes behind 'atest CtsAutoFillServiceTestCases' are not included in the material.