CVE-2025-22441 AI-generated analysis
platform/frameworks/base, core/java/android/widget/RemoteViews and core/java/android/appwidget/AppWidgetHostView (widget / RemoteViews inflation in host processes)
RemoteViews now builds the remote application Context from an ApplicationInfo fetched from PackageManager (keyed by package name and user id) instead of the parceled ApplicationInfo supplied by the RemoteViews-providing app, and the LoadedApk.checkAndUpdateApkPaths calls in RemoteViews and AppWidgetHostView are removed.
Root cause
When a host process inflated a RemoteViews, the code in RemoteViews.java that creates a Context for the remote app used the ApplicationInfo object (mApplication) read from the RemoteViews parcel/bundle supplied by the widget-providing app. It passed this object to LoadedApk.checkAndUpdateApkPaths(mApplication) and to context.createApplicationContext(mApplication, Context.CONTEXT_RESTRICTED). The commit message says the fields of this object could not be relied on to be accurate, so the host built a Context from data provided by the sending app. AppWidgetHostView.getRemoteContextEnsuringCorrectCachedApkPath also called LoadedApk.checkAndUpdateApkPaths on mInfo.providerInfo.applicationInfo before creating the application Context.
How the fix works
- core/java/android/widget/RemoteViews.java (the method that creates the application Context from mApplication, around line 6057; the hunk header does not show the method name): the call LoadedApk.checkAndUpdateApkPaths(mApplication) is deleted. The fix now gets a sanitizedApplication from context.getPackageManager().getApplicationInfoAsUser(mApplication.packageName, 0, UserHandle.getUserId(mApplication.uid)). Only the package name, and the user id derived from the parceled uid, come from the untrusted object.
- core/java/android/widget/RemoteViews.java (same method): context.createApplicationContext(sanitizedApplication, Context.CONTEXT_RESTRICTED) is called with the PackageManager-sourced object. The result is wrapped with applicationContext.createConfigurationContext(context.getResources().getConfiguration()); per the added comment, this gets the correct apk paths while keeping the current context's configuration. The existing catch (NameNotFoundException) now also covers the new getApplicationInfoAsUser call.
- core/java/android/appwidget/AppWidgetHostView.java:getRemoteContextEnsuringCorrectCachedApkPath: the lines that read expectedAppInfo = mInfo.providerInfo.applicationInfo and call LoadedApk.checkAndUpdateApkPaths(expectedAppInfo) are removed. The method still calls mContext.createApplicationContext(mInfo.providerInfo.applicationInfo, Context.CONTEXT_RESTRICTED). The android.app.LoadedApk import is removed from both files.
Completeness
- Covered: the RemoteViews path that turns the parceled mApplication into a Context now uses only packageName and uid (uid only to derive the user id) from the untrusted object; all other ApplicationInfo fields come from PackageManager.
- Not changed: mApplication.packageName and mApplication.uid are still read from the parcel without further validation. The code relies on PackageManager throwing NameNotFoundException for unknown packages.
- Not changed: the early-return check before the try block is kept as is; the material does not show its condition.
- AppWidgetHostView.getRemoteContextEnsuringCorrectCachedApkPath still passes mInfo.providerInfo.applicationInfo straight to createApplicationContext; only the checkAndUpdateApkPaths call was removed there. The material does not show where that object comes from or whether it can be trusted.
- The material does not show whether other uses of mApplication elsewhere in RemoteViews.java still trust parceled fields.
Behavior changes
- Each time a remote-app Context is created from a RemoteViews, the host process now does a PackageManager lookup (getApplicationInfoAsUser with flags 0).
- If the package named in the RemoteViews is not found for the derived user, NameNotFoundException is caught and logged instead of a Context being created from the parceled data. The code after the catch block is not shown.
- The returned Context is now a configuration Context built with the host context's current Configuration, instead of the raw application Context.
- LoadedApk.checkAndUpdateApkPaths is no longer called from RemoteViews or AppWidgetHostView.
Per major
- Android 14: same fix: commit 60335b2eae73 in android-security-14.0.0_r19 (two files, RemoteViews.java and AppWidgetHostView.java); at android-security-14.0.0_r29 all 8/8 lines of the patched region are present.
- Android 15: same fix: commit f60fc2258f63 in android-security-15.0.0_r7, with the same changes at different line offsets; at android-security-15.0.0_r17 all 8/8 lines are present.
- Android 16: not affected (not listed by the bulletin); at android-security-16.0.0_r8 all 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, 7/8 lines of the patched region are present.
Unknowns
- The name of the RemoteViews method containing the patched hunk, the exact early-return condition before the try block, and what the method returns after the NameNotFoundException catch.
- Which ApplicationInfo fields were misused and what the concrete EoP consequence was in the host process; the commit message only says the fields could not be relied on.
- Whether LoadedApk.checkAndUpdateApkPaths itself was changed or removed in a separate commit, and what it does internally.
- Where mInfo.providerInfo.applicationInfo in AppWidgetHostView comes from and whether it is trusted.
- Whether the layoutlib RemoteViews_Delegate.getApplicationInfo found by index search relates to this code path.
- Whether the CTS test RemoteViewsActivityTest#testApplicationInfo was added in this change or a separate one.