CVE-2026-99024
NoneCVSS
—
EPSS
0.2%
Published
Oct 23, 2026
CISA due date
—
Cloudanix analysis
A timing flaw in the Linux kernel's trusted execution support can let programs access hardware before it is ready, which may crash the system or allow misuse of kernel memory.
- Exploitation
- Local Privilege
- Attacker needs
- Local User
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- OS kernel
- Class
- Race Condition
- Remediation
- Patch
- Effort
- Low
- Patch risk
- Low
What it actually does
Race condition in optee_probe allows tee_device_register to expose /dev/tee* devices before struct optee fields (mutexes, completions, message cache, ctx pointer) are initialized, so early tee_open or tee_client_open_context calls dereference NULL or operate on uninitialized locks.
Why it matters to the business
Systems using the OP-TEE driver can experience kernel crashes or memory corruption shortly after module load, leading to unplanned downtime or potential local privilege escalation on affected Linux kernels.
How an attack unfolds
An attacker with the ability to trigger or race module initialization opens a TEE device file descriptor in the brief window after cdev_device_add succeeds but before optee_cq_init, optee_supp_init, and related setup complete, causing the kernel to use uninitialized state during session or invoke operations.
How to fix it
Update to a Linux kernel containing the fix that moves both tee_device_register calls until after full struct optee initialization; apply the patch or newer mainline/stable release that resolves the ordering issue.
How to confirm the fix worked
Confirm the optee_probe function performs all mutex, completion, cache, and ctx initialization before any tee_device_register call; verify the driver no longer registers devices with a partially constructed struct optee.
Typical attack path
- Load or trigger the optee kernel module on a system where OP-TEE is present
- Race tee_device_register calls by opening /dev/tee0 or /dev/teepriv0 immediately after device creation
- Perform TEE session open or command invoke before optee struct initialization finishes
- Trigger NULL dereference or uninitialized mutex use leading to crash or memory corruption
How to detect it
Examine kernel logs and module init traces around optee_probe for device registration preceding mutex and cache initialization; monitor for NULL pointer or mutex-related oops shortly after tee module load.
What your security team should do
- Prioritize kernel updates for any system exposing OP-TEE devices within the next patch cycle
- Review boot logs and dmesg for optee initialization sequences to identify exposure windows
- Consider temporary mitigation by disabling OP-TEE if the trusted execution environment is not required
The record
In the Linux kernel, the following vulnerability has been resolved: optee: register TEE devices only once fully initialized optee_probe() called tee_device_register() on both the client and the supplicant device before the rest of struct optee had been initialized. tee_device_register() calls cdev_device_add(), which does two things at once: it creates /dev/tee0 and /dev/teepriv0, and it links the device into the tee class so that class_find_device() can find it. From that moment on the device is reachable both from user space via tee_open() and from kernel space via tee_client_open_context(). The only gate in teedev_open() is tee_device_get(), which merely checks that teedev->desc is non-NULL, which was already set by tee_device_alloc(). Therefore, there is effectively no gate at all. A context opened in that window can run against a struct optee where - optee->call_queue.mutex is not initialized by optee_cq_init() - optee->supp mutex and completions is not initialized by optee_supp_init() - optee->rpmb_dev_mutex is not initialized yet, - the message argument cache is not initialized by optee_shm_arg_cache_init() - optee->ctx is still NULL Any open session or invoke during this window takes uninitialized mutexes and dereferences a NULL pointer. Fix it by moving both tee_device_register() calls down to the point where all of struct optee is set up. [JW: adding fixes and cc]
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|