CVE-2024-23713 AI-generated analysis
platform/frameworks/base, NotificationManagerService (notification listener filter migration)
In NotificationManagerService.migrateNotificationFilter, a VersionedPackage is now added to the listener's NotificationListenerFilter only when the resolved uid is not INVALID_UID, so packages whose uid cannot be resolved for a user are no longer stored in the filter.
Root cause
migrateNotificationFilter(INotificationListener token, int defaultTypes, List<String> disallowedApps) loops over the caller-supplied disallowedApps. For each profile of the listener's user it calls getUidForPackageAndUser(pkg, UserHandle.of(userId)), always wraps the result in new VersionedPackage(pkg, uid) and calls nlf.addPackage(vp). Only the exception path was treated as "pkg doesn't exist on that user; skip". When getUidForPackageAndUser returns INVALID_UID instead of throwing, the package was still stored in the NotificationListenerFilter and saved via mListeners.setNotificationListenerFilter(key, nlf). The new test reaches this case by making getPackageUid throw RemoteException for "apples", which suggests the helper turns that exception into INVALID_UID. The commit message's test step ('view policy xml file') suggests the filter ends up in the policy xml file.
How the fix works
- services/core/java/com/android/server/notification/NotificationManagerService.java, migrateNotificationFilter: the VersionedPackage creation and nlf.addPackage(vp) are now wrapped in `if (uid != INVALID_UID)`, so a package whose uid cannot be resolved for a given user is skipped for that user. The existing try/catch that skips on exceptions is unchanged.
- services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java: adds testMigrateNotificationFilter_invalidPackage. The test makes getPackageUid throw for "apples" on every user and resolves "bananas"/"cherries" to 9000/9001. It then asserts that the captured filter disallows the valid pairs and contains no entry named "apples". The test file also imports org.junit.Assert.assertNotEquals.
Completeness
- Covers the only place in migrateNotificationFilter where packages are added: the per-user loop now rejects INVALID_UID results as well as skipping on exceptions as before.
- Valid entries are unchanged: packages that resolve to a real uid are still added, and the defaultTypes handling (nlf.setTypes when areAllTypesAllowed) is untouched.
- The fix checks only the result of uid resolution. In the patched region it does not limit the size of the caller-supplied disallowedApps list or validate the package name strings themselves.
- The guard applies only to this migration path. Other code that fills or reads a NotificationListenerFilter is not in the material, so it is not shown whether that code rejects INVALID_UID entries on its own.
Behavior changes
- Packages in disallowedApps that do not resolve to a uid for a given profile are silently dropped for that profile instead of being stored with INVALID_UID. No error is returned to the caller.
- The saved listener filter (the policy xml, per the commit message's test step) no longer gets VersionedPackage entries with an invalid uid from this call.
Per major
- Android 14: same fix: commit ffd616dc3b91 in android-security-14.0.0_r7 (cherry-pick of bfa04e208995, Change-Id Ib7fcb733edd2cf2cbac0a7699763a5fe993b467e). At android-security-14.0.0_r29 all 8/8 lines of the patched region are present.
- Android 15: not affected per the bulletin. The fixed code (INVALID_UID guard) is present at android-security-15.0.0_r17 (8/8 lines).
- Android 16: not affected per the bulletin. The fixed code is present at android-security-16.0.0_r8 (8/8 lines).
- Android 17: not affected per the bulletin. The fixed code is present at android-security-17.0.0_r1 (8/8 lines).
Unknowns
- The material does not show the body of getUidForPackageAndUser, so when it returns INVALID_UID rather than throwing is inferred only from the test setup.
- What happens downstream with a saved INVALID_UID VersionedPackage (when the policy xml is read back or the filter is evaluated) is not shown. The bulletin only rates the issue as High EoP.
- Whether other writers of NotificationListenerFilter perform an equivalent uid check is not shown.
- The body of checkServiceTokenLocked, and so exactly which callers pass the token check, is not shown.