GhostLock: A 15-Year Bug in the Linux Kernel
A vulnerability called GhostLock, assigned [1] as CVE-2026-43499, has been hiding in the Linux kernel for over fifteen years. It exists in every major distribution since 2011, from kernel version 2.6.39 through 7.1. An unprivileged local attacker can use it to get root access. No special configuration, no capabilities, no user namespaces needed. Just regular threading syscalls.[2]
Google awarded the researchers $92,337 in kernelCTF for turning it into a 97% stable privilege escalation and container escape. The bug was found by VEGA, an automated kernel fuzzer, and disclosed by Nebula Security on July 7, 2026.[2]
What It Does
The vulnerability is a stack use-after-free in the rtmutex subsystem, specifically in the PI (priority inheritance) futex code. The root cause is a helper function called remove_waiter() that was written for one scenario, a thread cleaning up after itself, but got reused by the requeue-PI path to clean up on behalf of a different, sleeping thread.[2]
When a deadlock is detected during a futex requeue operation, the rollback path calls remove_waiter(), which clears current->pi_blocked_on. The problem is that current is the thread that issued the requeue, not the thread that owns the waiter. The waiter task keeps pi_blocked_on pointing at its own stack frame, which gets popped the moment it returns to userspace. Any later priority inheritance chain walk through that task follows a dangling pointer into freed stack memory.[2]
From there, the attacker can spray controlled bytes onto the freed stack location, forge a fake rt_mutex_waiter structure, and get two powerful primitives: write a pointer to an almost arbitrary address, or write 8 bytes of zero to an almost arbitrary address. Both lead to kernel control flow hijack and eventually root.[2]
How to Trigger It
Reaching the buggy code path requires a PI dependency cycle built from three futex words and three threads. The researchers describe the setup:
The waiter thread locks a PI futex called f_pi_chain, then blocks on a plain futex f_wait using FUTEX_WAIT_REQUEUE_PI. The owner thread locks f_pi_target (the requeue target), then blocks on f_pi_chain, which the waiter holds. Finally, the main thread calls FUTEX_CMP_REQUEUE_PI(f_wait -> f_pi_target). The chain walk detects the cycle, returns -EDEADLK, and the rollback takes the buggy path. The waiter wakes with a dangling pi_blocked_on.[2]
What makes this particularly nasty is that the UAF window is wide open. There is no race condition to win. The waiter sits in userspace with a dangling pointer, and the follow-up sched_setattr() that walks the chain can fire whenever the attacker likes. On a single CPU core, no less.[2]
The Fix
The fix is a single commit, 3bfdc63936dd, authored on April 21, 2026. It changes remove_waiter() to lock waiter->task->pi_lock and clear waiter->task->pi_blocked_on instead of using current. One line of code, conceptually. Fifteen years of vulnerability.[3]
Who Is Affected
Any Linux kernel between 2.6.39 and 7.1 without the fix is vulnerable, as long as CONFIG_FUTEX_PI=y (which is the default on virtually every distribution). There is no module to block, no configuration mitigation. The kernel needs to be updated.[3]
According to testing reported on the oss-security mailing list, Ubuntu with kernel 7.0.0-14 LTS is vulnerable and crashes when running the proof of concept. Debian 13 with kernel 6.12.95 and vanilla 6.6.144 are not vulnerable, likely because they already include the fix or have backported it. If your distribution hasn't updated its kernel in the past few months, you should check.[1]
Why It Matters
GhostLock is a good reminder that the Linux kernel is enormous, and some of its most dangerous bugs come from code paths that were never designed to interact. The remove_waiter() function was perfectly correct for its original purpose. It broke when the requeue-PI feature reused it for a scenario its author never imagined. This is the same pattern that produced Dirty COW, io_uring bugs, and countless other kernel vulnerabilities: a helper function gets a second caller, and the assumptions of the first caller don't hold for the second.[2]
It also highlights the value of automated kernel fuzzing. VEGA found this bug, not a human staring at code. The fuzzer generated inputs that exercised a deeply nested interaction between futexes, PI chains, and deadlock detection. A human reviewer would have to understand the entire requeue-PI state machine to spot that current and waiter->task can diverge. A fuzzer just tries things until something breaks.[2]
If you run Linux, update your kernel. If you run containers, update your host kernel. The fix has been in mainline since April, and most active distributions should have it by now. But "should" is not "does," and a 15-year bug doesn't care about your patching schedule.[3]
← All posts- oss-security mailing list post, "Linux: GhostLock / CVE-2026-43499 / stack-UAF and LPE in kernels 2.6.39 till 7.1," July 8, 2026. openwall.com ^
- Nebula Security, "IonStack part II: GhostLock, a stack-UAF that has existed in ALL Linux distributions for 15 years," July 7, 2026. nebusec.ai ^
- Linux kernel commit 3bfdc63936dd, "rtmutex: Use waiter::task instead of current in remove_waiter()," April 21, 2026. git.kernel.org ^