Android security tags, read closely by Lightrion

CVE-2025-22438 AI-generated analysis

platform/frameworks/native, inputflinger InputDispatcher (services/inputflinger/dispatcher)

AI-generated: written from the bulletin and the fixing diffs by claude-fable-5-1, then checked against the code by claude-opus-5-5 (7 corrections). Verify against the commit before relying on it.

In InputDispatcher::afterKeyEventLockedInterruptable, take a std::shared_ptr<EventEntry> copy and a local copy of hasForegroundTarget() from the DispatchEntry before the lock is released for policy calls, so the KeyEntry stays valid and the DispatchEntry is no longer dereferenced even if a concurrent removeInputChannel drains the connection's waitQueue and deletes the DispatchEntry.

Root cause

doDispatchCycleFinishedCommand looked up a DispatchEntry* in connection->waitQueue, built a KeyEntry& from dispatchEntry->eventEntry, and passed both to afterKeyEventLockedInterruptable. That function releases the lock to call into policy. While the lock is released, a removeInputChannel binder call can run. It drains the waitQueue and deletes the DispatchEntry. If the DispatchEntry held the last remaining reference to the EventEntry, the KeyEntry is freed too. The function then kept using the KeyEntry& and dispatchEntry->hasForegroundTarget(), which could point to freed memory. Per the commit message, in the observed flow the KeyEntry had been allocated by synthesizeCancelationEvents during a setFocusedWindow call.

How the fix works

Completeness

Behavior changes

Per major

Unknowns

Back to April 2025 · Findings