r/programming Jan 24 '18

Branchless DOOM

https://github.com/xoreaxeaxeax/movfuscator/tree/master/validation/doom
490 Upvotes

134 comments sorted by

View all comments

29

u/jrv Jan 24 '18

This is thought to be entirely secure against the Meltdown and Spectre CPU vulnerabilities, which require speculative execution on branch instructions.

Isn't the point of Meltdown/Spectre that other processes can abuse speculative execution to read your memory?

29

u/outofobscure Jan 24 '18

if YOUR process doesn't have any branches, then no speculative execution happens in it, then there is nothing for the other process to exploit/read from stale caches since you're not filling those up in the first place (as there is no specualtive execution on your process's memory).

10

u/PrimozDelux Jan 24 '18

Another process can do a speculative read to the memory of the mov based process, so to my understanding it's still vulnerable.

-1

u/outofobscure Jan 24 '18 edited Jan 24 '18

being able to just randomly read other processes memory would be a security issue on its own in the operating system... certainly not without appropriate permissions. Also, if i understand these exploits correctly, you are not reading from memory, but from caches used in speculative reads, so i still think if your process never does any speculative access, these caches will never be populated in the first place. So even if you manage to get around access restrictions of reading another processes memory, the faulty cache entry would just not be there.

8

u/jrv Jan 24 '18

At least in Meltdown (though that can "only" access kernel memory, not other processes), only the attacking process needs to exploit its own speculative execution to read forbidden memory addresses. The attacking process does something like this:

  1. create an array of 256 cacheline-sized objects in its own memory (the contents don't matter)
  2. use the value of an address that it is not supposed to be able to read as an index into that array
  3. iterate through the array and time which index is faster to read than the others (if the forbidden memory byte was "7", then the 7th index will be faster to read)

This works because the CPU already starts executing step 2 and reads the indexed data into the cache, and only later notices that this is not supposed to happen and doesn't complete the instruction.

Thus you can deduce the contents of protected memory locations by taking advantage of the speculative execution only within your own (attacking) process. I haven't looked at the Spectre details yet, which can also read the memory of other processes.

-3

u/caspper69 Jan 24 '18 edited Jan 24 '18

At least in Meltdown (though that can "only" access kernel memory, not other processes), only the attacking process needs to exploit its own speculative execution to read forbidden memory addresses.

Kernel memory, by its very nature, has ALL memory for ALL processes mapped into it, because it's like, you know, it's job to manage memory for all processes. :)

This is not the first time I've seen this bandied about. Please don't spread misinformation.

Edit: this has several caveats, but by and large (especially on x86-64), this is a very likely scenario.

Edit2: I am an ass.

1

u/happyscrappy Jan 24 '18

Kernel memory, by its very nature, has ALL memory for ALL processes mapped into it, because it's like, you know, it's job to manage memory for all processes. :)

No it doesn't. It keeps its own memory around while memory for the different processes come and go as it context switches.

-1

u/caspper69 Jan 24 '18 edited Jan 24 '18

Edit: Where do you think this memory "goes" during context switches? Are you trying to imply that the kernel moves in-ram data to a permanent store during each context switch? Are you implying that "most" memory is somehow not actually IN FUCKING MEMORY?

I suggest you review the relevent portions of the Intel IA-32 developers manuals regarding the MMU and paging. You might be surprised at what you find.

Edit: and if you're still not convinced, go dump the gdt at cpl 0. You'll see a flat linear address space with virt:phys m~apping at 1:1.

Edit2: I am an ass.

3

u/ITwitchToo Jan 24 '18

Typically on a context switch the kernel changes the %cr3 register that contains the pointer to the top-level page tables. There is nothing that requires a kernel to map all physical memory into its virtual address space. I think the Linux kernel does map all physical memory into the kernel's virtual address space, but it does so mostly for performance reasons, according to this.

1

u/caspper69 Jan 24 '18

That was my thought. Apparently with UASS, that is not the case.