> Or people could just understand the scope of the issue better
Do you understand the scope of the issue? Do you know that this couldn't personally affect you in a dragnet (so, not targeted, but spread out, think opportunistic ransomware) attack?
Because this statement of yours:
> Its not like you can write JS code with this that runs on browsers that lets you leak arbitrary secrets.
was not true for Spectre. The original spectre paper notoriously mentions JS as an attack vector.
If you truly disable all mitigations (assuming CPU and OS allow you to do so), you will reopen that hole.
So:
> The only real way this could ever be used is if you have direct access to the computer where you can run low level code.
I'm a low level kernel engineer, and I don't know this to be true in the general case. JITs, i.e. the JavaScript ones, also generate "low level code". How do you know of this not being sufficient?
>Do you understand the scope of the issue? Do you know that this couldn't personally affect you in a dragnet
The issue is not whether or not it could affect me, the issue is what is the risk. And I can say for certain that the risk is very low, because I seem to have more understanding of the space.
>The original spectre paper notoriously mentions JS as an attack vector.
In an analogy, having an attack vector is having a certain type of weapon, while executing a full exploit end to end is on the scope of waging a war. Sure, a right person at the right place with that weapon can take out a critical target and win the war, but just having that weapon doesn't guarantee you winning a war.
In the cases of certain exploits, like Log4Shell, thats like having a portable shotgun that shoots hypersonic missiles in a scatter pattern. Log4Shell basically means that if anything gets logged, even an error message, that can be used to execute arbitrary code, and its super easy to check if this is the case - send payloads to all services with a JNI url that you control and see what pops up, and boom, you can have shells on those computers.
In the case of Spectre/Meltdown, its like having a specific type of booby trap. Whether or not you can actually set up that booby trap highly depends on environment. If a website is fully protected against code injection, then executing JS cache timing would be impossible. And even if it wasn't, there would be other
Of course nothing is ever for certain. For example, browsers can contain some crazy logic bug that bypasses Same-Origin checks that nobody has found yet. But the chance of this happening is extremely low, as browser code is public.
Hmm, I'm not sure why Same-Origin and injection attacks are prerequisite. Shouldn't it be sufficient to visit an arbitrary website through a link somewhere?
This vulnerability is, in the worst case, about reading any memory in the system, not memory confined to any particular website, or to the browser at all, though?
Not quite. This vulnerability is reading memory that you can directly address.
If you can run arbitrary machine code on a system, that memory is the entire memory space (in theory) - you can assign a value to any pointer and attempt to read that address through side channel attack.
In reality the task is much harder - you don't know where in memory the thing you want is because of ASLR, virtual memory maps, and other factors, and to exploit cache timing attacks you need to have cache eviction happen first, and that's not really that straight forward for some memory addresses.
Javascript that runs in browser on the other hand has a lot more restrictions. You can't dereference a pointer to an arbitrary memory address in JS, you need an existing variable in the current context that is mapped to some memory.
I am really an amateur when it comes to Spectre-like attacks, but do you strictly need a valid pointer pointing to the address? I thought you "just" need to mispredict into code that would use it as a pointer, even if that code is never actually reached?
The paper demonstrates this by the C PoC using a system call as a gadget. Any value can be passed into the system call before it gets checked for validity on the other side of the kernel boundary. In their example, they use the "buffer" and "buflen" arguments to the keyctl system call, which results the values passed into the system call being in the registers r12 and r13. Then, they mispredict into a disclosure gadget that uses r12 and r13 for dereferencing pointers:
Note how "buflen" isn't even a pointer (for keyctl) to begin with, but the (as far as I understand) unrelated disclosure gadget code dereferences r13 (because it treats it as a pointer), and they managed to mispredict into it through keyctl's call to the "read" function pointer (this is the part where it's still a bit fuzzy to me, as I unfortunately don't fully understand the misprediction itself and how they control for arbitrary destinations).
Now, obviously you can't directly make system calls through JS. But I don't understand yet what, if anything, is in place to absolutely make sure that there are no indirect ways that result in a system call (or another path!) where benign, but arbitrary values get passed as arguments in registers, executing benign code, but being mispredicted into a different kernel code path where those registers would be used as pointers.
And then, once you can do that, you can affect almost arbitrary physical memory, since typically almost all physical memory is mapped in the kernel's address space.
Sure, this is much harder because of the layers in between, but I still don't quite understand why it's impossible, and why a sufficiently motivated attacker might not eventually find a workable solution?
Spectre just seems so fundamentally catastrophic for me, that anything but proper hardware fixes to how privilege boundaries are honored by speculative execution seems to merely make things harder to me, but how hard is a very non-trivial question for me. Is it hard enough?
(As for ASLR, in their paper they break that as their first step using their own methods.)
However, the BTB provides partial target addresses [28], so the attacker only needs to branch to an address where the lower portion matches the desired kernel target. The upper bits of the BTB target are provided by the victim branch source, which will be in the kernel address range. The technique follows the one we used in Section 6.1 and Figure 5.
So it seems to me that the actual difficulty from JS is less passing down the desired memory destinations (that's harder, yes, but I wonder if it's hard enough), but to generate (benign) branches to almost arbitrary addresses within the JS code, as it's probably neigh impossible to control for where those branches go.
Still, who really knows if there isn't some jump table generator or whatever to allow an attacker to generate branch targets arbitrarily enough (remember that it's not necessary to branch to the full address to train the branch predictor).
Because this would not be a vulnerability in any sense by itself. It would be yet another completely benign but unlucky piece of code that just allows the tire fire that Spectre is to be leveraged.
I'm probably missing other relevant aspects.
As for cache flushing, I think that's what the disclosure gadget does: "The disclosure gadget needs to use the two attacker-controlled registers to leak and transmit the secret via Flush+Reload", so that's also kernel code which we mispredict into. But I'm not totally sure.
You need to flush the addresses out of the cache in order for the branch predictor to speculatively execute and load the address back into the cache. This is where things get very tricky, because lets say you have some other process that accesses that address on a regular basis - it will get reloaded into the cache so your timing attacks have a lower chance of success.
So overall, putting together an exploit with this through JS becomes a matter of lots and lots of research and testing, for a specific target - i.e not worth the effort for anyone but a state sponsored agency.
Do you understand the scope of the issue? Do you know that this couldn't personally affect you in a dragnet (so, not targeted, but spread out, think opportunistic ransomware) attack?
Because this statement of yours:
> Its not like you can write JS code with this that runs on browsers that lets you leak arbitrary secrets.
was not true for Spectre. The original spectre paper notoriously mentions JS as an attack vector.
If you truly disable all mitigations (assuming CPU and OS allow you to do so), you will reopen that hole.
So:
> The only real way this could ever be used is if you have direct access to the computer where you can run low level code.
I'm a low level kernel engineer, and I don't know this to be true in the general case. JITs, i.e. the JavaScript ones, also generate "low level code". How do you know of this not being sufficient?