CVE-2026-12365 Use-after-free in Zephyr delayable work-queue cancellation under SMP timing race

Medium 5.8 Published Updated

A race condition in Zephyr's work queue allows use-after-free during cancellation, potentially causing kernel crashes or memory corruption in SMP builds.

Exploited in the wild
Not known
Login needed
Any signed-in user
Attackable
Local or same network only
Victim action needed
Not needed
Fix
None listed

What is CVE-2026-12365?

CVE-2026-12365 is a medium-severity use after free vulnerability in zephyrproject zephyr, published on 14 Aug 2026. It can only be exploited from the same machine or local network, with no action from the victim.

Official description

A use-after-free exists in the Zephyr second-generation work queue (kernel/work.c) in the handling of delayable work timeouts. When a delayable work item's timeout has been dequeued and its handler work_timeout() is in flight (blocked acquiring the work-queue spinlock), a concurrent cancellation does not wait for that handler to finish. In unschedule_locked() the pre-fix code called z_abort_timeout(), which for an already-announcing record returns -EINVAL without removing it; cancel_async_locked() then observes the work as idle, so even k_work_cancel_delayable_sync() and k_work_flush_delayable() return without blocking on the in-flight handler.

Because those are the APIs the kernel header documents as the safe way to cancel before freeing a k_work_delayable, a caller that frees the object immediately after a successful sync cancel can race the still-pending handler. work_timeout() subsequently dereferences the freed record: it reads to->dticks via z_is_timeout_handler_canceled() and, if the freed slot has been reused so the bail check fails, performs a read-modify-write of wp->flags (K_WORK_DELAYED_BIT) and submits work against a stale dw->queue pointer — a use-after-free read and write.

The k_work API is kernel-mode only (no __syscall entry point), so this is a kernel-internal concurrency defect rather than a userspace privilege escalation. Triggering it requires an SMP build and a subsystem that schedules and then frees (or reschedules) a delayable work item in the narrow window while its timeout is announcing; an attacker able to influence the timing of such teardown (for example via connection churn driving subsystem timers) has a plausible but probabilistic path. The impact is kernel memory corruption or crash (denial of service).

The fix makes unschedule_locked() wait, by spinning on z_try_abort_timeout() returning -EAGAIN while releasing and re-acquiring the work spinlock, until any in-flight handler completes before returning, and switches work_timeout() to atomic K_WORK_DELAYED_BIT ownership. This closes both the free-then-handler use-after-free and the related reschedule early-fire race.

Weakness: CWE-416

Which versions are affected by CVE-2026-12365?

How do I fix CVE-2026-12365?

No fix has been published for CVE-2026-12365 yet. Limit exposure of the affected software until one is available.

Upgrade to the fixed version. These bugs are found with fuzzing and sanitisers and avoided by memory-safe languages. More about Use after free.

Is CVE-2026-12365 being exploited?

There is no known exploitation of CVE-2026-12365 in the wild and no public exploit code.

Sources

Also known as GHSA-rhmh-r93p-6g99.

Is CVE-2026-12365 in your software?

Upload an SBOM and sbomify checks it against every vulnerability here, every day.

Check your SBOMs for free