GhostLock: The 15-Year-Old Linux Kernel Bug AI Found Hiding in Plain Sight
TL;DR
An AI-powered security agent discovered a Linux kernel vulnerability that has existed in every major distribution since 2011. It allows any unprivileged local user to gain full root access with a 97% success rate. There is no practical mitigation — patch your kernel.
| Attribute | Detail |
|---|---|
| CVE | CVE-2026-43499 |
| CVSS 3.1 | 7.8 (HIGH) — AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-416 (Use After Free) |
| Affected | Linux 2.6.39 through 7.0 |
| Fixed | Linux 7.1 (commit 3bfdc63936dd) |
| Stable backports | 6.1.177, 6.6.144, 6.12.95, 6.18.36, 7.0.13 |
| Not backported | 5.15.y, 5.10.y LTS |
| Discovered by | VEGA AI Agent (Nebula Security) |
| Bounty | $92,337 (Google kernelCTF) |
| Prerequisites | Local access, no special privileges, CONFIG_FUTEX_PI=y |
What Is GhostLock?
GhostLock (CVE-2026-43499) is a use-after-free vulnerability in the Linux kernel’s real-time mutex (rtmutex) priority-inheritance code. Specifically, it lives in the remove_waiter() function in kernel/locking/rtmutex.c.
The bug was introduced in Linux 2.6.39 (released in 2011) and was fixed in Linux 7.1. For over 15 years, it sat in the kernel’s scheduling subsystem — the code responsible for managing which processes get access to CPU time and in what order.
The Root Cause
The remove_waiter() function was written to clean up after a thread that blocks on a lock. It assumed that current (the thread currently executing) is always the same thread that owns the waiter object being cleaned up.
This assumption held for the normal slow-path — where a thread blocks on its own and cleans up after itself. But when the futex requeue-PI path was added, remove_waiter() started being called on behalf of a different, sleeping thread. In that path, current is the thread that issued FUTEX_CMP_REQUEUE_PI, not the thread that owns the waiter.
The result: remove_waiter() clears pi_blocked_on on the wrong task. The actual waiter task keeps pi_blocked_on pointing at a stack frame that gets freed when the waiter returns to userspace. Any subsequent priority-inheritance chain walk through that task follows a dangling pointer into freed kernel stack memory.
Why Lockdep Didn’t Catch It
Linux’s lockdep validator only checks that a pi_lock is held — it doesn’t verify whose lock it is. So the bug passed every automated lock-correctness check the kernel has for 15 years.
How to Trigger It
The exploit requires three futex words and three threads:
- f_pi_chain — a PI futex, locked by the waiter thread
- f_pi_target — a PI futex, locked by the owner thread (the requeue target)
- f_wait — a plain futex the waiter blocks on via
FUTEX_WAIT_REQUEUE_PI
The sequence:
- The waiter takes
f_pi_chain, then blocks inFUTEX_WAIT_REQUEUE_PI(f_wait → f_pi_target). Itsrt_mutex_waiterobject is now on its kernel stack. - The owner takes
f_pi_target, then blocks onf_pi_chain(which the waiter holds). - The main thread calls
FUTEX_CMP_REQUEUE_PI(f_wait → f_pi_target).
The requeue tries to proxy the waiter onto f_pi_target. The owner of f_pi_target is already blocked behind the waiter through f_pi_chain, so the chain walk detects a deadlock cycle: waiter → f_pi_target → owner → f_pi_chain → waiter. It returns -EDEADLK and triggers the buggy rollback.
The waiter wakes with a dangling pi_blocked_on. The UAF window is now wide open — there’s no time pressure. The attacker can trigger a follow-up sched_setattr() that walks the PI chain and dereferences the dangling pointer whenever they want.
Note that three threads is for better understanding. To win the race and trigger UAF, you only need one CPU core.
The Exploit Chain
Nebula Security’s exploit works as follows:
- Prefetch ASLR Leak — Uses CPU cache timing to leak the kernel image slide and physmap base address, defeating KASLR.
- Trigger GhostLock — Stage the three-futex cycle to leave the dangling
rt_mutex_waiterpointer. - Stack Reuse via
PR_SET_MM_MAP— Spray controlled bytes onto the freed kernel stack using theprctl(PR_SET_MM_MAP)syscall, forging a fakert_mutex_waiterstructure. - Controlled Write — The forged waiter passes kernel integrity checks and yields a constrained arbitrary write primitive.
- Hijack
inet6_protos[IPPROTO_UDP]— Use the write to modify the IPv6 protocol function table, redirecting a function pointer. - DirtyMode — Pivot from the function table hijack to
STATIC_USERMODE_HELPERoverwrite, achieving arbitrary code execution as root.
Success rate: 97% during testing. The exploit also works as a container escape — a privileged container can break out to the host kernel.
What’s Affected
| Component | Status |
|---|---|
| Linux 2.6.39 through 7.0 | Vulnerable |
| Linux 7.1+ | Patched |
| Stable backports: 6.1.177, 6.6.144, 6.12.95, 6.18.36, 7.0.13 | Patched |
| 5.15.y and 5.10.y LTS | Not patched (no backport) |
| Debian (testing) | Fixed in 7.0.4-1 |
| Proxmox VE 9 | Fixed in 7.0.14-4-pve |
| NixOS | Fixed in 6.18.38 |
| Amazon Linux 2023 | Fixed on all streams |
| Amazon Linux 2 | Terminal (end-of-life) |
| RHEL 8/9/10 standard kernel | Still affected (no RHSA yet) |
| CloudLinux | All supported versions fixed |
Partial Mitigations (Not Fixes)
| Mitigation | Effect |
|---|---|
RANDOMIZE_KSTACK_OFFSET | Makes stack reuse a 1/32 guess instead of deterministic. Still exploitable with retries. |
STATIC_USERMODE_HELPER | Closes this specific DirtyMode path but the technique generalizes to other /proc/sys knobs. |
Neither is a substitute for patching.
The AI Angle
The vulnerability was discovered by VEGA, an AI bug-hunting agent developed by Nebula Security. VEGA was designed to autonomously explore kernel code paths and identify potential vulnerabilities.
This isn’t the first AI-found bug in 2026. In June, Anthropic’s Mythos model identified vulnerabilities in classified US government systems during a testing exercise — NSA chief Joshua Rudd told Senator Mark Warner that Mythos “broke into almost all of our classified systems, not in weeks, but in hours.”
The pattern is clear: AI tools are finding bugs that human code review missed for 15 years. The question isn’t whether AI will replace security researchers — it’s how fast the gap between AI discovery and attacker adoption will close now that PoC code is public.
Proof of Concept
Multiple PoC implementations exist on GitHub:
1. MobiusM/CVE-2026-43499 (Primary PoC)
- Repo: github.com/MobiusM/CVE-2026-43499
- Stars: 99 | Forks: 26
- Language: C (91.8%), CMake (8.2%)
- Status: Working trigger — causes kernel panic on vulnerable devices
- Target: Android (uses NDK + adb), but the technique applies to any Linux system
- What it does: Triggers the UAF condition. Does not include the full privilege escalation chain — it demonstrates the vulnerability by crashing the kernel. The full exploit (root + container escape) is described in Nebula’s research but not all code is public.
Build & run:
cmake -B build -G Ninja
cmake --build build
adb push build/trigger /data/local/tmp/trigger
adb shell chmod +x /data/local/tmp/trigger
adb shell /data/local/tmp/trigger
Expected output on a vulnerable device ends with a kernel panic: Unable to handle kernel write to read-only memory
2. tc3650/CVE-2026-43499-armv7
- Repo: github.com/tc3650/CVE-2026-43499-armv7
- Target: ARMv7 devices (Android phones, IoT)
- Includes: Multiple exploit variants (8-iov spray, 3-iov variants, offset scanning)
- Status: More complete — includes variations targeting different kernel versions
3. pubglite55/oppo-ghostlock
- Repo: github.com/pubglite55/oppo-ghostlock
- Target: OPPO Find N2 (Snapdragon, specific kernel config)
- Status: Device-specific adaptation
4. Nebula Security’s Full Writeup
- URL: nebusec.ai/research/ionstack-part-2
- Includes: Complete technical analysis of the exploit chain, ASLR bypass, stack reuse technique, and DirtyMode escalation
- The Patch: Shows the one-line fix —
remove_waiter()useswaiter->taskinstead ofcurrent
5. Distro Patch-Status Tracker
- Repo: github.com/suominen/ghostlock
- What it does: Auto-updated tracker showing which distributions have backported the fix
- Maintained by: Claude Code (AI-maintained)
The Fix
The patch is elegantly simple. In remove_waiter(), instead of operating on current, it operates on waiter->task — the actual task that owns the waiter:
// BEFORE (vulnerable):
raw_spin_lock(¤t->pi_lock);
rt_mutex_dequeue(lock, waiter);
current->pi_blocked_on = NULL; // Wrong task!
raw_spin_unlock(¤t->pi_lock);
// AFTER (fixed):
struct task_struct *waiter_task = waiter->task;
scoped_guard(raw_spinlock, &waiter_task->pi_lock) {
rt_mutex_dequeue(lock, waiter);
waiter_task->pi_blocked_on = NULL; // Correct task
}
Commit: 3bfdc63936dd — “rtmutex: Use waiter::task instead of current in remove_waiter()”
Action Items
- Patch immediately if running Linux 2.6.39 through 7.0 on any internet-facing or multi-tenant system
- Check your kernel version:
uname -r— if it’s below 7.1 (or the stable backports listed above), you’re vulnerable - Prioritize: Cloud servers, containers, CI runners, and shared/multi-tenant hosts where local access is easier to obtain
- RHEL users: No RHSA exists yet for the standard kernel on RHEL 8/9/10. Monitor for updates and consider running a patched kernel from other sources if exposure is critical
- 5.15.y / 5.10.y LTS users: No backport exists. If you’re on these LTS branches, you need to upgrade to a newer kernel branch
Timeline
| Date | Event |
|---|---|
| 2011 (Linux 2.6.39) | Bug introduced in rtmutex rework |
| 2026-04-18 | Nebula Security reports bug to [email protected] |
| 2026-04-20 | Bug fixed with initial patch |
| 2026-05-04 | Fix backported to stable branches |
| 2026-06-30 | Google acknowledges kernelCTF submission, awards $92,337 |
| 2026-07-07 | Nebula publishes full technical writeup |
| 2026-07-12 | Cybernews publishes public coverage |
Sources
- Cybernews: AI discovers Linux bug that went unnoticed for 15 years
- Nebula Security: IonStack Part II — GhostLock Technical Writeup
- MobiusM/CVE-2026-43499 — PoC on GitHub
- The Hacker News: 15-Year-Old GhostLock Flaw Enables Root and Container Escape
- CloudLinux: GhostLock Kernel Update
- SecurityOnline: Public Exploit for GhostLock
- suominen/ghostlock — Distro Patch-Status Tracker