Heads up: posts on this site are drafted by Claude and fact-checked by Codex. Both can still get things wrong — read with care and verify anything load-bearing before relying on it.
why how

Why Spectre still isn't fully patched

Eight years after disclosure, new Spectre-class vulnerabilities keep landing. The reason isn't sloppy patching — it's that the attack exploits the same speculation that makes modern CPUs fast in the first place.

Security intermediate May 4, 2026

Why it exists

If you’ve ever wondered why a six-year-old laptop benchmarks worse on the same CPU than it did the day you bought it, part of the answer is mundane (thermal paste dries, fans clog) — but a measurable chunk is software. Since January 2018, every mainstream OS, browser, and hypervisor has been steadily piling on mitigations for a family of CPU bugs that started with two papers named Spectre and Meltdown. The patches cost performance — sometimes a few percent, sometimes much more for system-call-heavy workloads — and they keep coming. In just the last couple of years there’s been Inception, Downfall, Reptar, GhostRace, and a steady drip of variant disclosures.

The interesting question isn’t what Spectre is. It’s why the industry can’t just fix it and move on the way it does with normal CVEs.

The short answer is that Spectre doesn’t exploit a bug in the usual sense — a typo in a memcpy, a missing bounds check, a parser that trusts its input. It exploits the intended behavior of every fast CPU built since the late 1990s. Modern processors are fast largely because they don’t wait around: they guess what comes next, run it, and throw the work away if the guess was wrong. That guessing — speculative execution — is worth roughly an order of magnitude in single-thread performance. Spectre is the discovery that the “throw the work away” step is incomplete: the architectural state is reverted, but microarchitectural side effects (which cache lines got loaded, which branch predictor entries got updated) leak into the world, and an attacker can read them through timing.

You can’t fix Spectre by removing the bug, because the bug is the optimization. You can only narrow the channels through which the leak happens, one variant at a time, and pay for it in throughput.

Why it matters now

Spectre-class issues are the reason cloud providers behave strangely about SMT / hyperthreading on shared-tenant hardware — some have disabled it for certain workloads, others restrict cross-tenant pairings, because two threads on the same core sharing branch predictors and caches is exactly the topology these attacks exploit. They’re also why browser JavaScript engines lost access to high-resolution timers and SharedArrayBuffer was temporarily disabled in 2018: the threat model assumes attacker code is already running on your machine (in a tab, in a Lambda function, in a JS sandbox) and is just trying to read memory it shouldn’t be able to.

Most importantly, the meta-story keeps repeating. Researchers find a new way to coerce the CPU into speculating across a security boundary; vendors ship a microcode update or a compiler flag; six months later someone finds the next variant. The 2024 disclosures (e.g. GhostRace, BHI variants) were not fundamentally new physics — they were new paths through the same physics. Until CPUs are designed from the ground up with speculation isolated by security domain, the trickle is structural.

The short answer

Spectre = speculative execution + a microarchitectural side channel that survives the rollback

The CPU runs ahead of the program, executing instructions it isn’t yet sure are needed. If it guessed wrong, it discards the registers and pipeline state — but the cache, branch predictor, and other shared microarchitectural buffers keep the fingerprints of what it touched. An attacker tricks the CPU into speculating through a memory access it shouldn’t make (out-of-bounds, across a privilege boundary), then reads those fingerprints through timing. The “fix” is to plug the channels one by one, because the speculation itself is too valuable to remove.

How it works

The original Spectre variant (Kocher et al., 2018, arXiv:1801.01203) is the cleanest illustration. Imagine a kernel function that takes an integer index x from userspace and does:

if (x < array1_size) {
    y = array2[array1[x] * 4096];
}

The bounds check looks safe. With ASLR and the bounds check enforced, an out-of-range x returns immediately. But the CPU’s branch predictor doesn’t know the law — it learns from history. If you train it by calling this function repeatedly with valid x, it starts predicting “the branch is taken” by default. Now you call it once with an out-of-range x. The CPU speculates that the branch is taken, dereferences array1[x] even though x is out of bounds — that’s a kernel memory read, performed speculatively — uses the byte it found as an index into array2, and starts loading the corresponding cache line. Then the bounds check resolves, the speculation is squashed, registers are restored.

But the cache line is still loaded. The attacker times accesses to every page of array2; the one that comes back fast is the one that got speculatively touched, and its index reveals the secret byte. Repeat one byte at a time, and you’ve read kernel memory from a userspace process that was never given permission.

That’s Spectre v1: bounds-check bypass via the branch predictor.

Why “fix it” is harder than it sounds

Conceptually you’d patch this by either (a) not speculating across security boundaries, or (b) reverting the cache state when you revert the registers. Both are expensive.

So the actual mitigation portfolio is a patchwork: KPTI to address Meltdown (a related but separate Intel-specific bug where speculation crossed the user/kernel boundary even before privilege checks), retpoline for indirect branches, microcode updates for predictor barriers, browser-level reductions in timer precision, hypervisor-level core scheduling so VMs don’t share SMT siblings, and per-variant fixes as researchers find new channels.

Why new variants keep landing

The original Spectre paper named two variants and explicitly anticipated more. Researchers immediately started cataloguing the speculation primitives a CPU offers (indirect branches, return stacks, store-to-load forwarding, gather instructions, TSX transactional aborts) and the side channels available (L1/L2/L3 cache, TLB, store buffers, line-fill buffers, register file ports, even AVX2 register state). Cross every primitive with every channel and you get a matrix; each cell is a potential paper. The post-2018 disclosures — Foreshadow, MDS/RIDL/Fallout/ZombieLoad, LVI, Retbleed, Downfall (gather-data sampling), Inception (AMD return-stack injection), Reptar (Intel rep movsb corner case), GhostRace (race conditions in speculation) — are mostly cells in that matrix, not new physics.

The pattern is: someone proves that this speculative path leaks through that buffer; vendors add a microcode or compiler mitigation specific to that path; the matrix shrinks but the rest of it is still live.

What about hardware-fixed CPUs?

Vendors have been quietly redesigning. Intel’s post-2019 cores included silicon-level fixes for Meltdown and L1TF; AMD Zen 2/3/4 made architectural choices that immunized them against several variants but introduced others (Zenbleed, Inception). ARM’s newer cores have similar mixed records. The trend is toward “more of the obvious leaks closed in silicon,” not toward “a new architecture without speculation.” Nobody is willing to give up an order of magnitude of single-thread performance, and in any case the closer you look the more the channels multiply — speculative execution interacts with caches, predictors, prefetchers, memory ordering, and SMT in ways that don’t have a single chokepoint to defend.

What I’m not sure about

I’m being deliberately fuzzy on exact performance numbers. Published figures vary wildly — single-digit percent for compute-bound workloads, 20%+ for syscall-heavy workloads on early patches, less on newer hardware with silicon mitigations — and the right number depends on CPU generation, kernel version, which mitigations are enabled, and the workload. If you need a real number for a real decision, benchmark the actual machine.

I’m also compressing a lot of cross-vendor history. Intel, AMD, ARM, IBM POWER, and Apple Silicon each have different mitigation stacks and different vulnerability matrices. The shape of the story — speculation is the bug, the channel is microarchitectural state, the fix is per-variant — is the same; the specifics vary.

Going deeper