CVE-2025-0097 AI-generated analysis
platform/frameworks/base, WindowManager (services/core/java/com/android/server/wm: EmbeddedWindowController, WindowManagerService)
WindowManagerService.transferTouchGesture now records Binder.getCallingUid() before clearing the calling identity. EmbeddedWindowController.transferToHost and transferToEmbedded then throw a SecurityException unless that UID owns the transferFrom side (the embedded window owner or the host WindowState owner), so a process can no longer move an active touch gesture from a window it does not own.
Root cause
Before the fix, IWindowManager.transferTouchGesture(transferFromToken, transferToToken) only checked that the embedded window and the host WindowState were associated with each other. EmbeddedWindowController.isValidTouchGestureParams compares the mClient binder of the embedded window's host WindowState with the host's mClient, and checks that both sides have input channels. Nothing checked who was calling: Binder.clearCallingIdentity() ran before any use of the caller's identity. As the commit message describes, a host or embedded process that passed the association checks could therefore make InputManagerService.transferTouchGesture move the gesture in either direction, including taking an active gesture from its counterpart, without owning the transferFrom window.
How the fix works
- services/core/java/com/android/server/wm/WindowManagerService.java:transferTouchGesture: captures final int callingUid = Binder.getCallingUid() before Binder.clearCallingIdentity(), and passes it as a new first argument to both mEmbeddedWindowController.transferToHost(...) and mEmbeddedWindowController.transferToEmbedded(...).
- services/core/java/com/android/server/wm/EmbeddedWindowController.java:transferToHost(int callingUid, InputTransferToken embeddedWindowToken, WindowState transferToHostWindowState): after isValidTouchGestureParams passes, throws SecurityException("Transfer request must originate from owner of transferFromToken") if callingUid != ew.mOwnerUid. In this direction the embedded window is the transferFrom side.
- services/core/java/com/android/server/wm/EmbeddedWindowController.java:transferToEmbedded(int callingUid, WindowState hostWindowState, InputTransferToken transferToToken): after isValidTouchGestureParams passes, throws the same SecurityException if callingUid != hostWindowState.mOwnerUid. In this direction the host window is the transferFrom side.
- services/core/java/com/android/server/wm/WindowManagerService.java:grantInputChannel: adds Objects.requireNonNull(inputTransferToken), so an embedded window can no longer be registered without an InputTransferToken (hardening alongside the main fix).
Completeness
- Both transfer directions handled by transferTouchGesture get the owner check: embedded-to-host through transferToHost and host-to-embedded through transferToEmbedded. The existing association checks in isValidTouchGestureParams are kept and run first.
- The check compares UIDs only (callingUid vs mOwnerUid), not PIDs, so this fix does not tell apart different processes that share a UID.
- Because the owner check runs after isValidTouchGestureParams, requests with invalid or unassociated tokens still return false without a SecurityException. Only well-formed requests from a non-owner UID throw.
- The underlying InputManagerService.transferTouchGesture call is unchanged. The fix is entirely in the WindowManager entry point.
Behavior changes
- transferTouchGesture now throws SecurityException to the Binder caller when the calling UID does not own the transferFrom window (the embedded window owner or the host WindowState owner). Before the fix, such requests went ahead if the association checks passed.
- grantInputChannel now throws NullPointerException when inputTransferToken is null, instead of creating an EmbeddedWindow with a null token.
- EmbeddedWindowController.transferToHost and transferToEmbedded take a new leading int callingUid parameter.
Per major
- Android 14: Not affected per the bulletin (not listed). 0/8 lines of the patched region are present at android-security-14.0.0_r29.
- Android 15: Same fix, applied through a4a8fca641b0 in android-security-15.0.0_r5 (cherry-picked, Change-Id I2654ccab807a62a341c8af69bf64bb33e56c4252). At android-security-15.0.0_r17 the code context shows the owner checks in transferToHost/transferToEmbedded and the callingUid capture in transferTouchGesture (6/8 lines of the patched region matched).
- Android 16: Not affected per the bulletin (not listed). 4/8 lines of the patched region are present at android-security-16.0.0_r8. The material does not show the code form there.
- Android 17: Not affected per the bulletin (not listed). 4/8 lines of the patched region are present at android-security-17.0.0_r1. The material does not show the code form there.
Unknowns
- Whether isValidTouchGestureParams null-checks hostWindowState before dereferencing mClient is not shown, because the context starts mid-function. So the behaviour of transferToEmbedded with an unmapped transferFromToken is not visible in the material.
- The state of this code in Android 14, 16 and 17 is not shown beyond the line-match counts.
- Which client-side API surface exposes transferTouchGesture is not shown in the material.
- Whether the commit depends on other changes is not shown.