Live data from Hacker News

Zenbleed

lock.cmpxchg8b.com

241–250 of 378 posts

Re: Zenbleed

#241

Earlier quoted context omitted.

The valuable secret here would be the keys that let you decrypt and copy games. The threat models of locked-down platforms are incredibly strange.

That's a good point but I can't believe that every console doesn't have it's own unique set of keys so that if you compromise one before SW patches land, it won't be much use in the ecosystem.

It depends. I'm going to speak in general terms, since I obviously don't know how every single system works, but per-console keys are used for pairing system storage to the motherboard and maybe keeping save data from being copied from user to user. Most CDNs don't really provide the option for on-the-fly per user encryption, so instead you serve up games encrypted with title keys and then issue each console a title key that's encrypted with a per-console key. Disc games need to be encrypted with keys that every system already has, otherwise you can't actually use the disc to play the game.

As for the value of being able to do 'hero attacks' on game consoles, let me point out that once you have a cleartext dump of a game, you've already done most of the work. The Xbox 360 was actually very well secured, to the point where it was easier to hack a disc drive to inject fake authentication data into a normal DVD-R than to actually hack a 360's CPU to run copied games. That's why we didn't have widely-accessible homebrew on that platform for the longest time. Furthermore, you can make emulators that just don't care about authenticating media (because why would they) and run cleartext games on those.

Re: Zenbleed

#242

Earlier quoted context omitted.

After extracting the POC and installing build-essential, I still get this: nasm -O0 -felf64 -o zenleak.o zenleak.asm make: nasm: No such file or directory make: ** [Makefile:11: zenleak.o] Error 127

Install the nasm package. It's probably not included in build-essencial.

Thank you. I guess I should've read the error better, but I thought nasm was the thing complaining.

Re: Zenbleed

#243

Why does disabling SMT not fully prevent this? I don't know the details of Zen 2 architecture, but register files are usually implemented as SRAM on the CPU-die itself. So unless the core is running SMT, I don't understand how another thread could be accessing the register file to write a secret.

Because unless you pin the threads to certain CPU cores (e.g. in Linux by using the taskset command, or in Windows by using the Set Affinity command in Task Manager), they are migrated very frequently between cores. So even with SMT disabled, each core will execute sequentially many threads, switching every few milliseconds from one thread to another, and each context switch does not modify the hidden registers, it j…

Pinning doesn’t help either, since there will always be more threads than cores. Scheduling all those threads and even blocking on IO will cause context switches.

Re: Zenbleed

#244

This is super cool. This exploit will be one of the canonical examples that just running something in a VM does not mean it's safe. We've always known about VM breakout, but this is a no-breakout massive exploit that is simple to execute and gives big payoffs. Remember: just because this one bug gets fixed in microcode doesn't mean there's not another one of these waiting to be discovered. Many (most?) 0-days are kno…

In the case of the VM won't registers be wiped when entering/exiting the VM?

The problem is that the logical registers don't have a 1:1 relation to the physical registers.

For example, let's imagine a toy architecture with two registers: r0 and r1. We can create a little assembly snippet using them: "r0 = load(addr1); r1 = load(addr2); r0 = r0 + r1; store(addr3, r0)". Pretty simple.

Now, what happens if we want to do that twice? Well, we get something like "r0 = load(addr1); r1 = load(addr2); r0 = r0 + r1; store(addr3, r0); r0 = load(addr4); r1 = load(addr5); r0 = r0 + r1; store(addr6, r0)". Because there is no overlap between the accessed memory sections, they are completely independent. In theory they could even execute at the same time - but that is impossible because they use the same registers.

This can be solved by adding more physical registers to the CPU, let's call them R0-R6. During execution the CPU can now analyze and rewrite the original assembly into "R1 = load(addr1); R4 = load(addr4); R2 = load(addr2); R5 = load(addr5); R3 = R1 + R2; R6 = R4 + R5; store(addr3, R3); store(addr6, R6)". This means we can now start the loads for the second addition before the first addition is done, which means we have to wait less time for the data to arrive when we finally want to actually do the second addition. To the user nothing has changed and the results are identical!

The issue here is that when entering/exiting a VM you can definitely clear the logical registers r0&r1, but there is no guarantee that you are actually clearing the physical registers. On a hardware level, "clearing a register" now means "mark logical register as empty". The CPU makes sure that any future use of that logical register results in it behaving as if it has been clear, but there is no need to touch the content of the physical register. It just gets marked as "free for use". The only way that physical register becomes available again is after a write, after all, and that write would by definition overwrite the stale content - so clearing it would be pointless. Unless your CPU misbehaves and you run into this new bug, of course.

Re: Zenbleed

#245
post #184

Earlier quoted context omitted.

I think capability-pointer machines like CHERI might need in-bounds-only variants of these functions, too.

Generally CHERI tracks things for 16-byte regions

I think you might be confusing the tracking of validity of capabilities themselves (which could indeed be at a 16 byte granularity for an otherwise 64-bit system) with the bounds of a capability, which can be as small as 1 byte.

Re: Zenbleed

#246
post #191

Earlier quoted context omitted.

This is because VM means two different things and has for a long time: IBM's VM was and is a hypervisor. It dates to the mid 1960s, in the form of CP-40, and it didn't run opcodes in software, but in hardware. https://en.wikipedia.org/wiki/IBM_CP-40 p-code machines, which interpret bytecode, date back almost as far, such as the O-code machine for BCPL. https://en.wikipedia.org/wiki/BCPL Getting people to distinguish…

Looking at the IBM's tech from the sixties is somehow weirdly depressing: it's unbelievable how much of the architectural stuff they've invented already by the 1970.

I remember seeing VMware for the first time and thinking that the PC world had finally entered the 1970s.

Re: Zenbleed

#247
post #184

Earlier quoted context omitted.

I think capability-pointer machines like CHERI might need in-bounds-only variants of these functions, too.

Generally CHERI tracks things for 16-byte regions

Implementations using 32- or 64-byte (256 or 512 bit) vector extensions would run afoul of 16-byte granularity. While it is not common yet, ARM SVE allows vector sizes larger than 128 bits -- e.g., Graviton3 has 256-bit SVE and Fujitsu A64FX has 512-bit. (x86 has had 256 and 512 bit vector instructions for some time, but current CHERI development seems to be on ARM.)

Re: Zenbleed

#248
post #77

Earlier quoted context omitted.

Because the context switch only affects architectural state not microarchitectural state.

Yes I understand that but I was struggling to think of a sequence of instructions that would cause this secret leaking on a single thread. But a simple example is `vzeroupper` followed by anything that writes a secret to the same register file entry would be leaked on a subsequent flush.

It depends a bit on the exact details of the implementation, but there are several possibilities imaginable.

For example, a failed speculation of vzeroupper could result in it erroneously claiming a register by clearing the zero flag on the wrong register - which would mean that the previous data of that register is now suddenly available. If that register has not been touched since a context switch, it could leak data from another process.

The linked article has an animation which suggests that it clears the zero flag on the previously-used register - which indeed requires the victim to reuse the register in the small amount of time between it being marked as zero and the zero being cleared again.

However, the linked Github repo states:

> The undefined portion of our ymm register will contain random data from the register file. [..] Note that this is not a timing attack or a side channel, the full values can simply be read as fast as you can access them.

This suggests that it does indeed do something akin to clearing the zero flag of a random register.

Re: Zenbleed

#249
post #223

On my Zen2 / Renoir based system the PoC exploit continues to work albeit slowly even after updating the microcode (linked from TFA) that has the fix for this issue. The wrmsr stops it fully in its track. Edit: just realized it must have been that the initramfs image is not updated with the manually updated firmware in /lib/firmware. Edit2: Updated the initramfs and even if the benchmark.sh fails, ./zenbleed -v2 stil…

linux-firmware does not carry any microcode update for Renoir (yet). Or what do you mean by "TFA"? The fixed Renoir microcode should have revision >= 0x0860010b as per the kernel: https://github.com/torvalds/linux/commit/522b1d69219d8f08317...

TFA == The Fine Article :)

Updated microcode shows 0x08600106 revision so I guess that explains it.

Re: Zenbleed

#250

This is super cool. This exploit will be one of the canonical examples that just running something in a VM does not mean it's safe. We've always known about VM breakout, but this is a no-breakout massive exploit that is simple to execute and gives big payoffs. Remember: just because this one bug gets fixed in microcode doesn't mean there's not another one of these waiting to be discovered. Many (most?) 0-days are kno…

The problem is, VMs aren't really "Virtual Machines" anymore. You're not parsing opcodes in a big switch statement, you're running instructions on the actual CPU, with a few hardware flags that the CPU says will guarantee no data or instruction overlap. It promises! But that's a hard promise to make in reality.

The big switch statement wouldn't necessarily protect you either.
Post reply on HN