So, even if WebKit were entirely written in Rust, we'd still be fucked. I'm really starting to think it's about time for me to get out of this business.
So, even if WebKit were entirely written in Rust, we'd still be fucked. I'm really starting to think it's about time for me to get out of this business.
> But Spectre could theoretically involve any branch that enforces security properties, like the branches used for type checks in JavaScriptCore.
I get the impression this is all referring to JIT'd JS, not to the C++ (or Rust etc.) code powering the underlying engine (where all typechecking is done at compile-time anyway). Of course having the JS engine written in Rust would still allow the same, but it's been known for a long time that Rust's typesystem can't do squat to verify the correctness of dynamically-generated code; it's part of the reason why Mozilla only bothered to kick off a rewrite of Gecko and not SpiderMonkey.
Rust's `match` statement is a dynamic type check just like C++'s `dynamic_cast`. I bet you it's implemented using branches.
I wonder if this is a case of a difference in terminology, because enum variants (the branches in `match` expressions) aren't considered types in Rust, and have no interaction with Rust's typechecker (Rust always has to assume that every instance of an enum can be any variant, even in cases where we as the programmer know that only one variant is possible).
At the same time I'm still unclear on what the OP is trying to imply. To reiterate, AIUI Spectre can only read, not write, privileged memory, so it's impossible for a Spectre attack to trick the engine into believing that (to use Rust terminology) an instance of an enum is a variant that it isn't. Am I incorrect?
1) Write a function that reads the "nth" value out of an array in JS.
2) Call the function a bunch of times with JS arrays.
3) Pass an integer to that function for the "array" value. This would normally end up throwing. But before it does, the CPU might speculate the VM-internal typecheck as "it's going to be an Array, like the previous 1000 times" and end up doing an "nth value" read out of a memory address that you fully control (by changing which integer you pass).
That is, you can use speculative type confusion in the VM to allow precise control over what memory addresses get accessed and how for your timing attacks on the cache.
if is_pointer(pt):
// do pointer-based stuff
else:
raise error
If you train the branch predictor to expect a pointer, it will speculatively treat arbitrary values as pointers until it can determine that they are not. So you can pass in any value and get it treated like a pointer for the duration of the window of speculative execution.Any conditional branch is potentially vulnerable, an attacker just needs some sort of side effect from speculative execution that persists after rollback.
I’m not talking about research/example microprocessors that don’t have equivalent instructions. I mean isn’t branching a fundamental logical construct and we either do it in hardware with branch assembly operations or emulate functional equivalents of them in the software that runs on the microprocessor some other way? Or is there some clever/old logical/mathematical “alternative” to branches?
struct __internal_variable {
uint64_t type;
void *data;
}
uint64_t __last_type = [number of builtin types];
whenever you create a new type: increment __last_type and associate that type with the number;
uint64_t typeof(__internal_variable var) {
return var.type;
}
function[__last_type] typechecks;
functions[] = void function(uint64_t type) { failure; }
functions[int] = void function(uint64_t type) { success; }
functions[typeof(myvar)]()
If typeof(myvar) is int, then the function that returns success will be called, otherwise failure, no branches involved! Yes, it's a kludge, but it kind of works.---
Of course, you don't actually need this trick. If you put enough effort into it, you can essentially compile anything to c, after which you can just compile it with the movfuscator[1]
This is an architecture bug so any security check that relies on simple branching is potentiality vulnerable.
How do we stop his entire class of bugs? What is the Rust for CPU design?
> Since the 2010 Westmere microarchitecture Intel 64 processors also support 12-bit "process-context identifiers" (PCIDs), which allow retaining TLB entries for multiple linear-address spaces, with only those that match the current PCID being used for address translation.[19][20]
https://en.wikipedia.org/wiki/Translation_lookaside_buffer#P...
HN discussion: https://news.ycombinator.com/item?id=16094349
Spectre was more relevant to context.
Writing algorithms in parallel manner isn't as complicated as make to believe you, a lot can be rewritten based on cookbooks/patterns.
Intel developed a many-core CPU (72 CPU cores) called Xeon Phi: https://en.wikipedia.org/wiki/Xeon_Phi
Unfortunately they drifted of the target (instead of making it the successor of x86-64).
For Javascript engines, it would help if the offer an optional fallback "Javascript interpreter" instead of JIT. A JIT is basically at the moment insecure, especially when running untrusted code. The same goes for WebAssembly, let the user deactivate execution/support of it. Please allow end user to enable an alternative JS interpreter for high security things like online banking.
It's all abstracted in a very linear way.
Changing all that will take a lot of time if we do.
[1] outside of parallel iteration/folding constructs.
If they had ever released it as a general purpose computer instead of a locked down game console people could've experimented with it enough to unlock its full potential.
If they were smart they'd dust off the old chips, throw them on a RasberryPi type system and laugh all the way to the bank.
I vaguely remember that the price tag I saw was so outrageous I can understand why that didn't go anywhere.
Would have been interesting, though, I agree.
Intel iAPX 432 could have been it, but they did a lousy job implementing it.
There's WASM, but in that case the extra checks need to be applied at the WASM level, not the Rust level.
We are using index masking in WTF::Vector and WTF::StringImpl, which are used both for JavaScript execution and for lots of other things in WebKit that want a vector or a string.
(Not to say that a correctly-written Rust program wouldn't be vulnerable to Spectre for other reasons, of course.)
We are mitigating these branch-based type checks with pointer poisoning, and I don't think that those changes are biased in favor of C++ or JS, since both are vulnerable.
Maybe it is time to move to IT security business?