CVE-2024-0038 AI-generated analysis
platform/frameworks/base, accessibility (AccessibilityManagerService) and UiAutomationConnection
Adds caller checks to the two injectInputEventToInputFilter entry points: UiAutomationConnection now requires a trusted, connected, non-shutdown caller, and AccessibilityManagerService now enforces android.permission.INJECT_EVENTS before forwarding the event to the accessibility input filter.
Root cause
AccessibilityManagerService.injectInputEventToInputFilter is an @Override of IAccessibilityManager.Stub. After waiting for the input filter to be installed, it called mInputFilter.onInputEvent(event, FLAG_PASS_TO_USER | FLAG_INJECTED) without checking the caller. Likewise, UiAutomationConnection.injectInputEventToInputFilter forwarded directly to mAccessibilityManager.injectInputEventToInputFilter without the throwIfCalledByNotTrustedUidLocked / throwIfShutdownLocked / throwIfNotConnectedLocked guards that sibling methods such as syncInputTransactions and setRotation apply. Callers able to reach either Binder interface could therefore pass InputEvents to the accessibility input filter without a permission or UID check.
How the fix works
- services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java:injectInputEventToInputFilter: adds mSecurityPolicy.enforceCallingPermission(Manifest.permission.INJECT_EVENTS, "injectInputEventToInputFilter") as the first statement, before the mLock wait loop and the mInputFilter.onInputEvent call, so callers without INJECT_EVENTS are rejected by the security policy check.
- core/java/android/app/UiAutomationConnection.java:injectInputEventToInputFilter: adds a synchronized (mLock) block calling throwIfCalledByNotTrustedUidLocked(), throwIfShutdownLocked(), throwIfNotConnectedLocked() before forwarding to mAccessibilityManager.injectInputEventToInputFilter(event), matching the pattern of the adjacent syncInputTransactions and setRotation methods.
- Single commit; both hunks are independent additions. The test referenced is CtsAccessibilityTestCases:AccessibilityManagerTest.
Completeness
- Covers both entry points visible in the material: the service-side Binder method in AccessibilityManagerService and the UiAutomationConnection proxy method (call chain per index search: UiAutomation.injectInputEventToInputFilter -> UiAutomationConnection -> AccessibilityManagerService).
- The AccessibilityManagerService check enforces INJECT_EVENTS on any caller of the IAccessibilityManager method. The UiAutomationConnection check adds the trusted-UID, shutdown and connection guards used by the sibling methods in that class.
- The input filter wait loop and the onInputEvent forwarding are unchanged; only access control is added.
- No other callers or similar unchecked paths are shown in the material.
Behavior changes
- AccessibilityManagerService.injectInputEventToInputFilter now rejects callers lacking android.permission.INJECT_EVENTS through mSecurityPolicy.enforceCallingPermission.
- UiAutomationConnection.injectInputEventToInputFilter now throws if the caller is not the trusted UID, if the connection has been shut down, or if it is not connected (the same guards as its sibling methods).
Per major
- Android 14: same fix: commit 3e88d987235f in android-security-14.0.0_r5 (cherry-pick of e83d6c801bb4); 6/6 patched lines present at android-security-14.0.0_r29.
- Android 15: not affected per the bulletin; the patched region (6/6 lines) is present at android-security-15.0.0_r17.
- Android 16: not affected per the bulletin; the patched region (6/6 lines) is present at android-security-16.0.0_r8.
- Android 17: not affected per the bulletin; the patched region (6/6 lines) is present at android-security-17.0.0_r1.
Unknowns
- Which Android releases first introduced injectInputEventToInputFilter (the bulletin lists only 14 and 14-next).
- The implementation of mSecurityPolicy.enforceCallingPermission and the exact exception it throws (not shown in the material).
- Which calling identity UiAutomationConnection uses when it calls AccessibilityManagerService.injectInputEventToInputFilter, and whether that identity holds INJECT_EVENTS (not shown).