CVE-2024-43085 AI-generated analysis
platform/frameworks/base, services/usb (UsbDeviceManager, USB function switching and accessory mode)
In UsbDeviceManager's USB function-switch timeout handling, when the current function is FUNCTION_ACCESSORY the fix now calls notifyAccessoryModeExit (which sets FUNCTION_NONE, notifies the permission manager of accessory removal and clears mCurrentAccessory) instead of re-enabling the screen-unlocked default USB functions.
Root cause
In services/usb/java/com/android/server/usb/UsbDeviceManager.java, the handler case for the function-switch timeout (the case containing 'operationId = sUsbOperationCount.incrementAndGet(); if (msg.arg1 != 1)') unconditionally called setEnabledFunctions(mScreenUnlockedFunctions, false, operationId), with the comment that the default function may be selected from Developer options. If the timeout occurred while mCurrentFunctions == UsbManager.FUNCTION_ACCESSORY, the device switched to those default functions rather than FUNCTION_NONE, and the accessory-exit bookkeeping in notifyAccessoryModeExit (usbAccessoryRemoved, clearing mCurrentAccessory) was not performed.
How the fix works
- UsbDeviceManager.java, function-switch timeout handler case (msg.arg1 != 1 branch): adds 'if (mCurrentFunctions == UsbManager.FUNCTION_ACCESSORY)' and calls notifyAccessoryModeExit(operationId) in that case; otherwise keeps setEnabledFunctions(mScreenUnlockedFunctions, false, operationId).
- UsbDeviceManager.java, notifyAccessoryModeExit: visibility changed from private to protected (the diff does not state why). Per the r29 context (lines 822-834) it logs 'exited USB accessory mode', calls setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId), and if mCurrentAccessory != null calls mPermissionManager.usbAccessoryRemoved(mCurrentAccessory) (when mBootCompleted) and clears mCurrentAccessory.
- Net effect: a timeout while in accessory mode now ends in FUNCTION_NONE (no data transfer) with accessory state cleared, matching the existing non-timeout accessory-exit path (context lines 814-815) which already called notifyAccessoryModeExit.
Completeness
- Only the function-switch timeout handler case is changed; the normal accessory exit path (lines 814-815) already used notifyAccessoryModeExit and is untouched.
- The new condition is an exact equality test on mCurrentFunctions == UsbManager.FUNCTION_ACCESSORY; a combined mask including accessory with other bits would not match (USB functions are bit flags in UsbManager (general platform knowledge)). The material does not show whether such combinations can occur here.
- Other call sites of setEnabledFunctions(mScreenUnlockedFunctions, ...) are not shown in the material and are not modified by this commit.
- The fix does not change the timeout duration or the msg.arg1 == 1 branch.
Behavior changes
- On a function-switch timeout while the current USB function is FUNCTION_ACCESSORY, USB functions are set to FUNCTION_NONE instead of the screen-unlocked default functions.
- In that case mPermissionManager.usbAccessoryRemoved(mCurrentAccessory) is invoked (if boot completed), mCurrentAccessory is cleared, and 'exited USB accessory mode' is logged.
- notifyAccessoryModeExit is now protected rather than private.
Per major
- Android 14: same fix: commit 2457d4e459ee in android-security-14.0.0_r14 (cherry-pick of 7c6ec68537ba, Change-Id I698e9df0333cbb51dd9bd5917a94d81273a2784a); at android-security-14.0.0_r29 7/8 lines of the patched region are present; the shown context confirms notifyAccessoryModeExit is protected, the timeout-handler hunk is not in the shown context.
- Android 15: same fix with an additional cosmetic hunk: commit f46d19f31d8f in android-security-15.0.0_r2 also reorders the android.text.TextUtils import; at android-security-15.0.0_r17 8/8 lines of the patched region are present.
- Android 16: not affected (not listed by the bulletin); at android-security-16.0.0_r8 7/8 lines of the patched region are present.
- Android 17: not affected (not listed by the bulletin); at android-security-17.0.0_r1 6/8 lines of the patched region are present.
Unknowns
- The exact message constant name for the function-switch timeout case is not shown in the diff.
- Why notifyAccessoryModeExit was made protected (e.g. subclass or test access) is not shown.
- Whether mCurrentFunctions can hold a combined mask including FUNCTION_ACCESSORY in this handler.
- Other callers of setEnabledFunctions(mScreenUnlockedFunctions, ...) and whether other paths have the same fallback.
- How accessory mode is entered and what access an attacker needs; which default function the EoP rating assumes.