SEPTEMBER 18, 2026
Live Feed
Back to database
Case File

CVE-2026-12631

MEDIUM · CVSS 6.5 EPSS 0.15% Public Exploit

Source: NVD + CISA KEV + EPSS · Published 2026-08-18 · Last synced 2026-09-17

CyberRota Analysis

AI-Generated

The vulnerability affects the Zephyr kernel's handling of the k_thread_join() and k_thread_abort() system calls, allowing unprivileged user-mode threads to exploit improper validation checks and potentially crash the kernel or bypass access controls. This can lead to a locally triggerable denial of service, as the kernel may enter an illegal instruction trap or exhibit undefined behavior, depending on the compiler used. Organizations utilizing the Zephyr kernel, especially those with user-space configurations, should prioritize patching this vulnerability to mitigate the risk of service disruption and unauthorized access.

Public Exploit Signal

A public exploit, PoC, GitHub repository or Metasploit reference was detected for this CVE.

Note: these links are listed for security research and verification purposes only.

CVE
CVE-2026-12631
Severity
MEDIUM
CVSS
6.5
EPSS
0.15%

Original NVD Description

The Zephyr kernel validates the k_thread_join() and k_thread_abort() system calls (declared __syscall in include/zephyr/kernel.h) through thread_obj_validate() in kernel/thread.c. Its default switch branch is the access-denied path, taken when k_object_validate() returns -EPERM (the calling user thread was never granted access to the target thread object) or -EBADF (the supplied pointer is not a registered kernel object of the right type). That branch invoked K_OOPS(K_SYSCALL_VERIFY_MSG(ret, "access denied")), but K_SYSCALL_VERIFY_MSG treats a true expression as success; the non-zero error code ret therefore read as "verified OK", the kernel oops was never raised, and control fell through to CODE_UNREACHABLE. Because k_thread_join() and k_thread_abort() are system calls, an unprivileged user-mode thread (under CONFIG_USERSPACE) can reach this denial path directly by calling either syscall on a thread object it does not own. Instead of the offending thread being cleanly terminated, execution reaches __builtin_unreachable() while running in supervisor mode inside the syscall handler. On Clang builds CODE_UNREACHABLE emits an illegal-instruction trap, so a user thread can deterministically crash the kernel — a locally triggerable denial of service that escapes the userspace sandbox. On GCC builds the path is undefined behavior: the compiler may drop the return-value handling for thread_obj_validate(), so it can return an undefined bool; if that is false, the caller proceeds into the real k_thread_join()/k_thread_abort() implementation for a thread the user was never authorized to access, an access-control bypass. The fix changes the verification expression to ret == 0, so a denied (non-zero) result now correctly raises K_OOPS and terminates the offending caller.