CVE-2024-49732 AI-generated analysis
platform/frameworks/base, Companion Device Manager (services/companion, CompanionDeviceManagerService binder impl)
Adds a system-UID caller check to the three hidden permission-sync binder entry points (enablePermissionsSync, disablePermissionsSync, getPermissionSyncRequest) in CompanionDeviceManagerService, so that non-system callers get a SecurityException instead of reaching SystemDataTransferProcessor.
Root cause
In services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java, the binder-exposed methods enablePermissionsSync(int associationId), disablePermissionsSync(int associationId) and getPermissionSyncRequest(int associationId) passed calls straight to mSystemDataTransferProcessor with no caller check. Several nearby methods do carry @EnforcePermission and call *_enforcePermission(). Per index search, SystemDataTransferProcessor.enablePermissionsSync only calls mAssociationStore.getAssociationWithCallerChecks(associationId) and then writes a PermissionSyncRequest with setUserConsented(true) to mSystemDataTransferRequestStore. So a caller that passed the association check could record user consent for permission sync without going through a system-mediated flow. The bulletin rates the issue as High-severity EoP.
How the fix works
- CompanionDeviceManagerService.java: enablePermissionsSync. Before handing off to mSystemDataTransferProcessor.enablePermissionsSync, the method now checks getCallingUid() != SYSTEM_UID and throws SecurityException("Caller must be system UID").
- CompanionDeviceManagerService.java: disablePermissionsSync. The same SYSTEM_UID check is added before mSystemDataTransferProcessor.disablePermissionsSync.
- CompanionDeviceManagerService.java: getPermissionSyncRequest. The same SYSTEM_UID check is added before returning mSystemDataTransferProcessor.getPermissionSyncRequest.
- The check is a strict UID equality, not a permission check, so only callers running as the system UID can use these three APIs. All other callers are rejected at the binder entry point before the processor (and its association lookup) is called.
Completeness
- Covers exactly the three hidden permission-sync binder methods. Each gets the same gate, placed before any processing, and SystemDataTransferProcessor logic is unchanged.
- Does not modify SystemDataTransferProcessor itself. Per index search, its enablePermissionsSync still relies only on getAssociationWithCallerChecks. Through the binder, it is now reachable only by system-UID callers.
- The adjacent binder methods enableSystemDataSync and disableSystemDataSync (r17 context, lines 637-645) still have no @EnforcePermission annotation or UID check. The material does not show whether their delegate (mAssociationRequestsProcessor) does its own authorization.
- The client wrapper CompanionDeviceManager.enablePermissionsSync is not changed. Enforcement is server-side only.
Behavior changes
- enablePermissionsSync, disablePermissionsSync and getPermissionSyncRequest now throw SecurityException("Caller must be system UID") for any caller whose UID is not SYSTEM_UID. Clients using the binder interface (including the CompanionDeviceManager wrapper) receive this SecurityException.
- No change for callers running as the system UID.
Per major
- Android 14: Not affected per the bulletin. At android-security-14.0.0_r29, 0/6 patched lines are present. The material does not show whether these binder methods are absent in 14 or present without the check.
- Android 15: Same fix, resolved via bug_id in android-security-15.0.0_r4 (cherry-pick of internal commit 08f57da9e398, Change-Id I9771ce38728d40b026d94cb6785d55f144c66790). 6/6 lines present at android-security-15.0.0_r17.
- Android 16: Not affected per the bulletin (not listed). 6/6 patched lines present at android-security-16.0.0_r8.
- Android 17: Not affected per the bulletin (not listed). 6/6 patched lines present at android-security-17.0.0_r1.
Unknowns
- Whether the methods exist in Android 14 (0/6 lines could mean the code is absent or unpatched). The bulletin lists only 15 and 15-next.
- What mAssociationStore.getAssociationWithCallerChecks actually enforces, and so how broad the set of possible callers was before the fix.
- What disablePermissionsSync and getPermissionSyncRequest in SystemDataTransferProcessor do and whether they perform caller checks (only enablePermissionsSync is shown).
- Whether SYSTEM_UID and getCallingUid were already in scope in the class before the fix.
- No test was added (the commit says Manual test), so the material shows no in-tree regression coverage.