CVE-2026-0096 AI-generated analysis
platform/packages/apps/Settings, Bluetooth (ForgetDeviceDialogFragment)
Settings' Bluetooth forget-device dialog fragment now loads app labels via ApplicationInfo.loadSafeLabel (MAX_SAFE_LABEL_LENGTH, TRIM | FIRST_LINE flags) instead of the raw PackageManager.getApplicationLabel, so app-supplied labels are sanitized before use in the dialog.
Root cause
ForgetDeviceDialogFragment.getAppLabel(String packageName) returned mPackageManager.getApplicationLabel(mPackageManager.getApplicationInfo(packageName, 0)) with no sanitization (no length limit, trimming or first-line restriction). The fragment imports AssociationInfo, CompanionDeviceManager and ListFormatter, which suggests the labels belong to companion apps associated with the device and are combined into the dialog text. The material does not show that code directly. The application label is defined by the app itself, so unsanitized app-controlled text could reach the Settings confirmation dialog.
How the fix works
- src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java:getAppLabel: replaces mPackageManager.getApplicationLabel(ApplicationInfo) with ApplicationInfo.loadSafeLabel(mPackageManager, PackageItemInfo.MAX_SAFE_LABEL_LENGTH, TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE). Adds the android.content.pm.PackageItemInfo import (android.text.TextUtils was already imported). The NameNotFoundException path (log and return "") is unchanged.
- tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java: the mock setup now stubs appInfo.loadSafeLabel(mPackageManager, MAX_SAFE_LABEL_LENGTH, TRIM | FIRST_LINE) on the mocked ApplicationInfo instead of mPackageManager.getApplicationLabel(appInfo). Imports PackageItemInfo and TextUtils.
Completeness
- Covers the label-loading path in ForgetDeviceDialogFragment.getAppLabel, the only production code changed by the diff.
- Sanitization is limited to what loadSafeLabel does with the MAX_SAFE_LABEL_LENGTH size argument and the TRIM and FIRST_LINE flags.
- No other call sites are changed. Per index search, other getAppLabel helpers elsewhere in the platform still use loadLabel without safe-label flags (see potential_variants). Other helpers, such as CredentialManager DataConverter.getAppLabel and PermissionController Utils.getAppLabel, already use loadSafeLabel.
Behavior changes
- App labels shown via getAppLabel in the forget-device dialog are now limited by the MAX_SAFE_LABEL_LENGTH argument, trimmed and reduced to their first line, so long or multi-line labels render differently than before.
- Label loading now goes through the ApplicationInfo instance (loadSafeLabel) instead of PackageManager.getApplicationLabel, which changes how tests must mock it.
Per major
- Android 14: not affected per bulletin. At android-security-14.0.0_r29, 6/8 lines of the patched region are present. No fix shown.
- Android 15: not affected per bulletin. At android-security-15.0.0_r17, 6/8 lines of the patched region are present. No fix shown.
- Android 16: same fix: commit 24b35b078f39 in android-security-16.0.0_r7 (cherry-pick of 08db8c5058a3, Change-Id I49bf86eec5e1402b5797f5a8118b96e7505c3877, Bug 473005624), linked by bug_id. 7/8 lines present at android-security-16.0.0_r8.
- Android 17: same fix: commit 62b7a2483f4e in android-17.0.0_r1 (base). Identical source diff. The test hunk differs only in line offsets. 7/8 lines present at android-security-17.0.0_r1.
Unknowns
- How the app labels are combined into the dialog text, and what else the dialog shows (for example the Bluetooth device name), is not shown.
- How package names reach getAppLabel (the AssociationInfo handling) is not shown.
- Which aconfig flag gates the companion-app part of the dialog, and whether it is enabled on shipping Android 16 builds.
- Why Android 14/15 are not affected cannot be determined from the material beyond the partial line match.
- The exact semantics of the MAX_SAFE_LABEL_LENGTH size argument to loadSafeLabel are not shown.