GHSA-86xj-2q6x-h82w: Time-of-check/time-of-use double fetch in the Zephyr i3c_transfer() syscall handler allows kernel-mode control-flow hijack from user mode
The user-mode verification handler for the i3ctransfer() system call, zvrfyi3ctransfer() in drivers/i3c/i3chandlers.c, validated the caller-supplied struct i3cdevicedesc in place instead of snapshotting it. It confirmed only that the descriptor was readable by the calling thread (KSYSCALLMEMORYREAD()), read target->bus once to check it with KSYSCALLOBJ(), and then passed the caller's live pointer down. The implementation zimpli3ctransfer() re-reads target->bus from that user memory and dispatches through it as DEVICEAPIGET(i3c, target->bus)->i3cxfers(...), so the bus that was validated is not necessarily the bus that is used. DEVICEAPIGET() performs no runtime type check outside CONFIGDEVICEAPIASSERT builds.
On a build with CONFIGUSERSPACE and an I3C controller driver, a user thread that has been granted an I3C device object can exploit this with a second thread in the same memory domain: one thread calls i3ctransfer() while the other rewrites the bus field of the descriptor. The window between the check and the use spans the nummsgs validation, the message-array access check, a stack VLA allocation and a memcpy() of up to 32 struct i3cmsg, so the race is repeatable and can simply be retried until it lands.
When the substitution succeeds, the kernel dereferences an attacker-chosen pointer as a struct device, loads a function pointer from the attacker-controlled api table and calls it in supervisor mode with attacker-influenced arguments. This yields kernel-mode code execution from an unprivileged user thread — a complete escape of the userspace memory-protection sandbox; lesser outcomes are an arbitrary two-level kernel read or a kernel fault. Builds without CONFIGUSERSPACE, or without an I3C driver, are unaffected.
The fix copies the descriptor into a kernel-stack local with kusermodefromcopy(), validates the bus in that copy, and dispatches on the copy, so the validated value is provably the value used.
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
Build without CONFIG_USERSPACE; builds without CONFIG_USERSPACE are unaffected.
Zephyr CONFIG_USERSPACE = disabled