---
id: "CVE-2026-99024"
kind: "vulnerability"
aliases: ["CVE-2026-99024"]
title: "Linux kernel OP-TEE driver: device opened before init lets local users crash or take over"
severity: "unknown"
cvss: null
epss: null
exploited: false
status: "open"
category: "runtime"
products: []
ecosystems: []
tags: ["arm", "linux-kernel", "optee", "runtime"]
not_affected_if: ["no-optee-driver"]
published_at: "2026-10-23T13:17:25+00:00"
first_seen_at: "2026-10-23T21:57:33+00:00"
updated_at: "2026-10-25T04:55:36+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-99024", "first_seen_at": "2026-10-23T21:57:33+00:00"}]
---

# Linux kernel OP-TEE driver: device opened before init lets local users crash or take over

The OP-TEE driver in the Linux kernel registers its TEE device nodes before its internal structures and locks are set up, so a context opened in that window uses uninitialized mutexes and a NULL pointer. The sources do not state what an attacker gets beyond a likely kernel crash or memory corruption.

_Summary, check and fix written by a model from the sources; labelled as such._

## How to check

- `uname -r` and compare against the kernel release that contains the fix, which the sources do not name
- Check whether the OP-TEE driver is in use: `ls /dev/tee0 /dev/teepriv0`
- unknown for a definitive version list

## Fix

- Update the Linux kernel to a release that includes the upstream commit moving tee_device_register() calls after full initialization (version unknown from sources)
- unknown for a specific version number

## Timeline

- 2026-10-23T21:57:33+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-99024

## From the sources

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]

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
