CVE-2026-12364
When a syscall verifier does nothing — when it simply passes arguments through without bounds checking or memory access validation — you're looking at a security contract that exists on paper but not in code. CVE-2026-12364 is exactly that: a logging function in Zephyr RTOS declared with __syscall, paired with a verifier that performs zero validation, allowing userspace to trigger arbitrary kernel memory reads through what should have been a hardened boundary. The fix adds K_SYSCALL_MEMORY_READ() and bounds checks — the same pattern used by every other verifier in the Zephyr kernel. That this pattern was known, documented, and used elsewhere in the codebase is the critical observation. This wasn't a hard problem solved incorrectly; it was a solved problem not applied. The gap exists because someone wrote a pass-through verifier, no reviewer caught it, and the tooling that generated or template-copied that verifier didn't require the checks by default. Here's what makes this worse than a typical missing-check bug: the logging subsystem is the exfiltration channel. The attacker doesn't need a write primitive — the logging backends are the write mechanism. Kernel memory read via the vulnerable syscall flows directly into debug UART, network logging, flash storage, or ring buffers. On embedded targets, UART output is often persistent and externally observable. One malicious log message can dump arbitrary kernel memory to attacker-observable channels. The 'no write primitive' caveat in CVE descriptions undersells this: the read primitive feeds directly into a system designed to propagate its output. This is also not an isolated failure. CVE-2023-0779, CVE-2022-29153, and CVE-2021-39698 all involve the same pattern — missing K_SYSCALL_* checks in verifier stubs. Each was patched individually. None triggered a tooling fix. Each new __syscall declaration in Zephyr is a potential CVE until someone manually applies the known pattern. The generation tooling still produces unhardened stubs by default. Audit your __syscall declarations. If the verifier is a pass-through, it needs the K_SYSCALL_MEMORY_READ() and bounds checks. Prioritize logging, output, and diagnostic functions — these are the subsystems that connect arbitrary reads to observable outputs, making them the highest-value targets for this class of flaw.
Reviewed through automated stages and approved by a human before publication.