AMD's ASID blocks the issues for VM guests (and root users on VM guests).
For variant 2, Project Zero used the eBPF interpreter as a gadget, a fake branch destination, without having to actually create an eBPF program or use the normal userland-facing eBPF APIs at all. And they only chose it as the least "annoying" option (see quote below).
edit: I'm not sure how ASID support would mitigate either of those variants, though there may be something I'm not thinking of. (It would help with variant 3, but that's the variant AMD wasn't vulnerable to in the first place.)
quote:
> At this point, it would normally be necessary to locate gadgets in the host kernel code that can be used to actually leak data by reading from an attacker-controlled location, shifting and masking the result appropriately and then using the result of that as offset to an attacker-controlled address for a load. But piecing gadgets together and figuring out which ones work in a speculation context seems annoying. So instead, we decided to use the eBPF interpreter, which is built into the host kernel - while there is no legitimate way to invoke it from inside a VM, the presence of the code in the host kernel's text section is sufficient to make it usable for the attack, just like with ordinary ROP gadgets.
I totally understand how the breaking out of the javascript sandbox attack works and the fact that IPT won't help with that. With Linux's clone(), you could clone without CLONE_VM and use CLONE_NEWUSER|SYSVMSEM and then unmap everything except the Javascript interpreter / JIT and leave a shared memory map and communicate only via the shared memory map and SYSV semaphores for synchronisation. Obviously this wouldn't be available on other platforms.
For variant 1, you would need to find some legitimate kernel code, accessible by syscall, that looks at least somewhat similar to the example in the Project Zero blog post:
if (untrusted_offset_from_caller < arr1->length) {
unsigned char value = arr1->data[untrusted_offset_from_caller];
unsigned long index2 = ((value&1)*0x100)+0x200;
if (index2 < arr2->length) {
unsigned char value2 = arr2->data[index2];
}
}
In practice, you may not be able to find something nice like "((value&1)*0x100)+0x200", but even if it simply used 'value' as an index, you would be able to at least narrow it down to a range. Other code patterns may work too (and potentially be more powerful?), e.g. conditional branches based on 'value'.For variant 2, see caf's answer to you in another thread.
The attack allows to read all the memory. Isn't there a way to scan for passwords or ssh keys and turn that into a privilege escalation?
KASLR is not enabled everywhere, and where it is, there are other attacks to defeat it, which are mentioned in the paper.
See the section "Reading host memory from a KVM guest / Locating the host kernel". It's terribly clever.
What I was wondering was for local OS user mode to local OS root / kernel mode access; i.e. user to kernel privilege escalation.
What would block it is flushing the branch predictor state when switching privilege levels and/or address spaces.
If I'm understanding the post correctly it says that JIT's not required for Intel CPUs, but is required for AMD.
BPF is employed by the `bpf()` syscall for socket packet filtering, as well as by `seccomp` itself for its syscall filtering. Is this threat vector not available to untrusted processes?
https://elixir.free-electrons.com/linux/v4.15-rc6/source/ker...