Meltdown attack depend on (speculatively) accessing the target virtual address directly (from within the attacking process)1.
But Spectre is not. You prime the branch predictor so that the code under attack speculatively accesses its own virtual address space, which it has permission to do. Branch-predictor aliasing means you can usually / sometimes prime the prediction for a branch at a virtual address you can't / don't have mapped. (e.g. in the kernel.)
The usual side-channel, a cache-read attack, is based on evicting the cache for an array in your own address space. But other side-channels are possible to get the Spectre data from the target back to the attacker, like priming the cache and then looking for which entry was evicted by a conflict-miss for an address which aliases some memory in the process under attack. (Harder because L3 cache in modern x86 CPUs uses a complex indexing function, unlike simpler caches which use a simple range of bits as the index. But possibly you could use L2 or L1d misses.
L2 miss / L3 hit should still be measurably longer than an L2 hit.)
Or with SMT (e.g. Hyperthreading), an ALU timing attack where the Spectre gadget creates data-dependent ALU port pressure. In this case the only relevant memory access is the data under attack (which is allowed by the hardware, only mis-speculation of the branch causes a rollback, not a load fault).
When attacking the kernel, it will have the physical memory pages of the attacking process mapped somewhere. (Most kernels map all of physical memory to a contiguous range of virtual addresses, allowing easy access to any physical address.) Caching is based on physical addresses, not virtual.
A Spectre gadget that makes a cache line hot via a different mapping for the same page still works.
In the context of a system call, the kernel usually keeps user-space memory mapped to the same virtual addresses it was using inside the process, so system calls like read
and write
can copy between user-space and the pagecache. And many system calls pass user-space pointers to filenames. So when attacking the kernel, a Spectre gadget can directly use user-space addresses in the attacking process.
The Spectre gadget itself could maybe even be in user-space memory, although with separate page tables to work around Meltdown, you might mitigate that by setting the kernel page tables to have user-space VAs mapped without exec permission.
Footnote 1: Meltdown is a bypass for the U/S bit in the page tables, allowing user-space to potentially read any memory the kernel leaves mapped. And yes, [1] is a sufficient workaround. See http://blog.stuffedcow.net/2018/05/meltdown-microarchitecture/.