Meltdown Attack
- Every CPU has Speculative Execution, that allows the CPU to process something before deciding if the process has the permission or not.
- If a user-level process accesses a memory location, the data is stored in the cache. When the CPU finds out that the permission is not available, it rollbacks the registers and instruction pointer (architectural rollback), but the CPU does not evict the cache lines that were filled due to out-of-order execution.
1. Memory Array Initialization: probe_array allocates $256 \times 4096$ bytes. Array index $i$ is separated from index $i+1$ by exactly $4\text{ KB}$, isolating every potential byte value onto its own physical memory page to block hardware prefetcher interference.
2. Microarchitectural Flush: _mm_clflush() explicitly purges all 256 candidate lines from L1, L2, and L3 caches to reset the memory channel state before speculative execution begins.
3. Fault Catching Setup: sigsetjmp marks a safe checkpoint in user space. When the kernel instruction triggers SIGSEGV, siglongjmp intercepts the signal and restores execution without crashing the attacker's process.
4. Transient Assembly Load:
movb (%0), %al: Loads privileged kernel memory into registeral. The CPU flags an architectural permission fault, but out-of-order hardware speculatively executes subsequent lines before the fault retires.shlb $12, %al: Multiplies the secret byte by $4096$ (2^12shift)movb probe_array(%rax), %al: Accessesprobe_array[secret * 4096], pulling that specific candidate line into L1 cache speculatively.
5. Flush+Reload Timing Scan: __rdtscp() counts raw CPU clock cycles while dereferencing each candidate page line. An access completing under ~80 cycles indicates the line was loaded into cache during transient execution.
6. Statistical Decoding: Running the attack loop over 1,000 samples eliminates random cache noise caused by background OS interrupts. The index with the highest hit count represents the recovered secret byte.