Skip to content

GoFetch: Will people ever learn?

2024/04/18

Last month researchers reported that the data memory-dependent prefetcher (DMP) on Apple M1 chips can be used to break encryption. (And there are indications that similar attacks might be possible on Intel silicon.)

Triggering the prefetcher results in greatly reduced access latency, i.e. a leak (from the GoFetch paper).

The researchers observe that any (64-bit) aligned data word, whose value matches bits [53:32] of its own address, is considered a pointer by the DMP. The DMP then speculatively dereferences this putative pointer and loads the target word into the (shared) L2 cache. The attack, dubbed GoFetch, is pretty ingenious: By feeding specific data (as cleartext) to an encryption process, and using prime&probe for observing the L2 state (as indicated in the figure), they can determine bits of the secret key, based on whether the DMP prefetches.

There are a number of interesting (in the Chinese sense?) observations to make here.

The mechanism was known to pose security problems

… but that problem didn’t seem to be taken seriously, presumably because no realistic attack was demonstrated. Specifically, the Augury work, published two years earlier, showed that DMPs could lead to disclosing memory contents, but the responsible people (in this case, Apple) didn’t seem to care.

Unfortunately that’s a consistent pattern of denial that ranges across the community and industry: Some academics point out that there’s a problem, but yeah, my system hasn’t actually been hacked, so I’ll just ignore it.

I’ve been through this myself. I’ve long been worried about exploiting microarchitecture for covert channels, and demonstrated how they could be systematically prevented, the approach we ended up calling time protection. Our argument was that if there’s a covert channel (allowing a Trojan to intentionally leak data) then that’s a problem. Because most systems execute plenty of untrusted code that must be assumed to contain such a Trojan, or could be highjacked into serving as a Trojan. (And, besides, any covert-channel mechanism has a high risk that someone will find a side channel, i.e. unintentional leakage, based on the same underlying mechanism.)

This only changed with the Spectre attacks: Spectre uses speculative execution to construct a Trojan from gadgets in innocent code, which then uses the covert channel to extract information. (And most people falsely talk about Spectre using a side channel, which doesn’t help raising awareness of this problem.)

Obviously, taking security seriously means dealing with problems proactively, not only when the horse has bolted. But that’s not how industry and our discipline seems to operate.

Time protection defeats the GoFetch attack (and many others)

Time protection (here colouring the L2 cache) is effective in closing channels. Top is the unmitigated channel, bottom with time protection applied. These are channel matrices, any fluctuation along a horizontal cut indicates a channel.

The core idea of time protection is to spatially or temporally partition any contented microarchitectural resource between security domains. In the case of the L2 cache (used in the GoFetch exploit) this means partitioning between concurrent processes (eg. by cache colouring). This means that the attacker can only influence the state of its own cache partition (same holds for the victim, i.e. the encryption process in the case of GoFetch) and the prime&probe attack fails.

There will, no doubt, appear variants of GoFetch exploiting different parts of the microarchitecture (as there are by now several variants of Spectre), but time protection will stop them all, as it is a principled approach that completely prevents any microarchitectural timing channels between security domains.

Note that we also found that complete time protection is not possible on contemporary processors, as they lack a mechanism for resetting all microarchitectural state that cannot be spatially partitoned (that includes all on-core state). However, our collaborators at ETH Zurich demonstrated (constructively, by implementing it as a new instruction, fence.t, in an open-source RISC-V processor core) that adding such a mechanism is easy and cheap. So, why not just do it?

… But people keep inventing ad-hoc point solutions

While time protection is a principled approach to completely prevent microarchitectural leakage, and thus defeats the whole class of attacks that depend on them (which includes Spectre, GoFetch and many others, but also any Trojan in untrustworthy code), people keep inventing ad-hoc band-aids for specific attacks, which end up making hardware more complex (and thus error-prone) and only end up shifting the attackers’ efforts to the next battlefield. A great example of this is speculation-taint tracking, which massively complicates hardware, but won’t prevent new attacks (eg is unlikely to stop GoFetch).

It’s disheartening that the authors of the GoFetch paper fall in the same trap. They write:

Longer term, we view the right solution to be to broaden the hardware-software contract to account for the DMP. At a minimum, hardware should expose to software a way to selectively disable the DMP when running security-critical applications.

In other words, expose DMP at the HW-SW interface, making it (and software based on it) massively more complex, just for dealing with one specific attack vector.

I’m all in favour of improving the HW-SW contract. In fact, we have argued for years that this is needed!

But rather than exposing more implementation details that limit the flexibility of hardware designers, the extension should be minimal and high-level, as we have proposed: Identify which resources can be spatially partitioned (and how), and providing a mechanism for resetting all microarchitectural resources that cannot be spatially partitioned. The latter is exactly that fence.t is – a simple, principled mechanism that can be used to knock out a whole class of attacks.

And some shocking revelations by the OpenSSL maintainers

Much of the above is what I’ve come to expect. Annoying, but unsurprising.

What actually shocked me was this quote from the Disclosure section of the GoFetch paper:

OpenSSL reported that local side-channel attacks (i.e., ones where an attacker process runs on the same machine) fall outside of their threat model.

Read this again…

Taken at face value, this means that OpenSSL is not fit for purpose if you have any untrusted code on your machine, i.e. any code that you cannot be sure not to be malicious. This includes any third-party code that could contain a Trojan, or any code that has a bug that allows it to be highjacked.

Think about it. This means that OpenSSL is not fit for purpose on:

  • a cloud hosting service that co-locates VMs/services from different users on the same physical machine (i.e. almost all of them)
  • your phone that almost certainly runs apps that come from developers you cannot trust to produce bug-free code
  • your laptop that almost certainly runs programs that come from developers you cannot trust to produce bug-free code
  • most likely your car

The mind boggles.

Houston, we have a problem

Does anyone care?

Leave a Comment

Leave a comment