Back to Articles

CPU Microarchitectural Attacks: How Speculative Execution and Cache Timing Leak Kernel Secrets

CPU Microarchitectural Attacks: How Speculative Execution and Cache Timing Leak Kernel Secrets
Photo from Sendly Team / Unsplash

Software security models rest on an inviolable hardware guarantee: user-space applications cannot read memory belonging to the operating system kernel or other processes. Memory management units (MMUs) enforce privilege rings (Ring 0 for kernel, Ring 3 for user). But in 2018, computer scientists uncovered a terrifying reality: modern CPU performance optimizations—specifically Speculative Execution, Branch Prediction, and Hardware Caching—allow unprivileged JavaScript running in a web browser to read raw kernel memory, encryption keys, and passwords across hardware security boundaries.

1. The Need for Speed: Branch Prediction and Speculative Execution

Modern CPUs operate in nanoseconds, while system RAM operates in tens or hundreds of nanoseconds. If a CPU had to wait for RAM every time it encountered an if condition, processors would spend 90% of their cycles idling.

To avoid this stall, modern CPUs use Speculative Execution: the processor guesses which branch of an if/else statement will execute based on historical patterns (Branch Predictor) and executes those instructions ahead of time out of order. If the guess turns out to be wrong, the CPU rolls back the architectural registers as if the instructions never ran.

2. The Fatal Flaw: The Microarchitectural Footprint

While the CPU rolls back its architectural registers (e.g. RAX, RBX), it does not roll back changes made to the hardware CPU cache!

[Speculative Execution Leak Pattern]
1. if (x < array1_size) {
2.     uint8_t value = kernel_secret[x];      // Privilege violation!
3.     uint8_t temp = array2[value * 4096];   // Loads specific cache line
4. }

When x is out of bounds:
- Architectural State: Rolled back. CPU throws exception or discards results.
- Microarchitectural State: array2[value * 4096] remains in L1/L2 Hardware Cache!

Even though the operating system forbids the program from accessing kernel_secret[x], the CPU speculatively executed the instruction before the bounds check completed, pulled the secret value into internal execution units, and used it to load an address into the CPU hardware cache.

3. The Flush+Reload Cache Timing Attack

How does the attacker extract the secret value from the cache? By measuring execution time down to individual CPU clock cycles using the RDTSC assembly instruction.

  1. Flush: The attacker flushes array2 from the CPU cache using the clflush instruction.
  2. Trigger Speculation: The attacker feeds an out-of-bounds index, causing the CPU to speculatively load array2[secret * 4096] into the cache before realizing its mistake.
  3. Reload & Measure: The attacker reads every index of array2 (0 through 255) and measures how many nanoseconds each read takes.

Index 0 through 41 take ~200 CPU cycles (retrieved from slow RAM). But index 42 returns in just 20 CPU cycles! The attacker instantly knows that secret == 42 (which corresponds to the ASCII character '*'). Repeating this loop leaks kernel memory at rates up to several megabytes per minute.

4. Meltdown vs. Spectre: What Is the Difference?

  • Meltdown (CVE-2017-5754): Exploited speculative execution bypassing privilege checks (reading kernel memory directly). It was fixed via KPTI (Kernel Page Table Isolation), which completely unmaps kernel address space while running in user space.
  • Spectre (CVE-2017-5753 / CVE-2017-5715): Tricked the branch predictor into executing speculatively inside another application's context. Spectre is fundamentally harder to fix because it targets core CPU speculative design and requires software mitigations like Retpolines, serializing fences (LFENCE), and site isolation in web browsers.

5. The Performance Tax of Hardware Security

The mitigations for microarchitectural side-channel attacks came with a heavy cost: initial patches slowed certain cloud database and virtualization workloads by 5% to 25% due to the overhead of constant TLB (Translation Lookaside Buffer) flushes and branch serialization. Today, newer hardware architectures (Intel Alder Lake/Arrow Lake, AMD Zen 4/5, Apple Silicon) build native hardware-level speculation barriers directly into silicon execution pipelines.

Frequently Asked Questions

Can a website read my passwords through a web browser using Spectre?

When Spectre was discovered, malicious JavaScript could indeed exploit cache timing. In response, modern browsers (Chrome, Firefox, Safari) drastically reduced the resolution of performance.now() (adding random timing jitter) and implemented strict Process-Per-Site Isolation so that different tabs cannot share CPU memory space.

Can antivirus software detect side-channel attacks?

Traditional signature-based antivirus cannot detect cache timing attacks because the malicious code executes entirely within standard, benign CPU instructions without writing files to disk.

PREVIOUS ARTICLE
The Raft Consensus Algorithm: How Distributed Databases Agree on Truth During Network Partitions

In a single-server architecture, consistency is trivial: the CPU executes transactions sequentially, and changes commit to a single disk. But in modern distribu...

NEXT ARTICLE
Zero-Knowledge Proofs (ZKPs) Explained: How zk-SNARKs and zk-STARKs Prove Truth Without Revealing Secrets

In conventional computing, proving that you know a secret or that a complex computation was executed faithfully requires revealing either the secret itself or t...