On WebKit Security Updates
blogs.gnome.org
blogs.gnome.org
This is not necessarily a bad thing as it allows much more interaction between user and server. But complexity often means more bugs, and thus more vulnerabilities.
Just look at the list: http://webkitgtk.org/security/WSA-2015-0002.html "Memory corruption and application crash" appears more times than I can count.
The problem is of course that software has to be designed for this, it's not something that can easily be slapped on as an afterthought. It demands more of the design, and that's not easy to motivate in most organisations. Forcing the developer to take security into consideration would be better, but the root of the problem is that most organisations don't consider security that important, even if they say they do.
AFAIK, (but it's entirely likely that I'm ignorant) there is no mainstream seccomp or capsicum sandboxed browser.
pcwalton works on Rust, I believe. A rendering engine written in a memory-safe style is something humanity just needs to build and I applaud Mozilla in at least starting down that long road with Servo.
That said, HTML5 has sprawled to the point that it appears (to me) essentially unimplementable from scratch unless you are Google, Microsoft or Apple. That seems like a problem. If web servers indicated what HTML features a page they were serving needed, it'd let browsers pick different rendering engines on the fly, but of course ... malicious web pages would simply always ask for the least secure engine. There doesn't seem to be a good workaround for that. It's the downside of trying to force the web into being an app platform.
It's also unclear to me how the balance between safe and unsafe code works out in Rust. Looking at Servo it appears that unsafe code is used all over the place including in very core parts:
https://github.com/servo/servo/search?utf8=%E2%9C%93&q=unsaf...
My guess is that Rust's memory model simply requires unsafe code more often than a traditional GCd range checked language does. A part of me wishes the Java guys would hurry up and get value types done already (it's years away), as combined with a lot of the auto-vectorisation optimisations being added at the moment by Intel it feels like at that point a performance competitive rendering engine written in entirely memory safe code would become realistic. Perhaps it even already is, unfortunately none of the above mentioned companies are interested in trying and nobody else can afford HTML5.
This line of thought is how I ended up concluding we need an entirely new mobile code oriented app platform.
I disagree. Both Java and .NET are memory safe and both have supported some form of VM-level isolation for many years. Sure, the kind of missed-length-check-leads-to-complete-compromise we're used to from C is very rare, but at least Java is full of hole anyway.
Process-granularity sandboxing gives a clear hardware-assisted security boundary that can be quite difficult to break through.
tl;dr memory safety is great but it does not replace sandboxing.
That's a very misleading characterization. It's less than 1% of the code. And it should be in core parts: those are the parts that are carefully audited and the parts that safe abstractions are built around.
We need unsafe primarily for the FFI layer, just as you do in any language. Bindings to a JIT would be no less safe in Java. You just have to write "unsafe" to call FFI functions in Rust, because we want to make it easier to audit that code.
> combined with a lot of the auto-vectorisation optimisations being added at the moment by Intel it feels like at that point a performance competitive rendering engine written in entirely memory safe code would become realistic
Any compiler developer will tell you that pinning your hopes on autovectorization is a lost cause. And you need a lot more than SIMD to write a competitive browser engine. (SIMD isn't the reason we write unsafe.) What I'd like to know is how you propose to write a JIT in safe code, without trusting that the JIT is implemented correctly. There are ways to potentially do that in theory (proof carrying code), but they're way beyond anything you've mentioned.
By "core code" I meant the first results are things like layout code, a file called string_list.rs, string_multimap.rs etc. That doesn't sound like stuff at the edges to me.
Any compiler developer will tell you that pinning your hopes on autovectorization is a lost cause
I didn't mean that's the only thing that's needed, I think value types would be by far the biggest needle-mover there. But there's quite a lot of auto-vectorisation going on in the latest JIT compilers, a surprising amount (some of it not released yet).
What I'd like to know is how you propose to write a JIT in safe code, without trusting that the JIT is implemented correctly
Obviously if you're compiling code, the compiler has to generate safe outputs. But take a look at how the Graal/Truffle frameworks do it. Graal is a JIT compiler implemented entirely in Java. It generates machine code that's then handed off to the JVM for execution. Truffle sits on top and uses aggressive partial evaluation to convert AST interpreters for dynamic scripting languages into JIT compilers automatically. They have a Javascript implementation that's comparable to V8 in speed, and you can interop with it through safe APIs. Again, the entire compiler/JIT stack is written entirely in a safe language: eventually the CPU jumps to the result, but the code itself is all written in a safe way.
As for string lists and such, those are core collections. Again, those are low-level primitives and relatively easy to prove safe. We should be migrating more of that code to the safe language, but it never causes problems in practice. That's because the "build simple abstractions out of unsafe primitives and keep the complicated code safe" approach works. (We have empirical evidence that it works, you know. There are incredibly few segfaults in Servo relative to any other browser engine we've worked on.)
I am convinced that writing in Java would not make the browser any safer. All you'd do is to move some unsafe code from the engine to HotSpot. The only real effect it would have is that the word "unsafe" would not appear as often in the code.
> It generates machine code that's then handed off to the JVM for execution.
And there is absolutely no difference between that and what Servo/SpiderMonkey does, because you're trusting the millions of lines of code in HotSpot. Servo is just being explicit about the lack of safety when touching the JIT.
I'd love to know more about why, that seems mad in 2016.
The latter is easily explained: Webkit (especially on Linux) is woefully short of manpower now that Google et. al. have pulled out of it.
I'll call myself lucky if WebkitGTK doesn't crash on any of the Alexa top 100 any more.
And here I thought we'd finally get a quality browser-engine for our OS. Seems we'll have to wait some more :)
Seems it's where we're headed for now.
So IIRC, Webkit doesn't really have first class support for sandboxing as Apple has 'their own' sandboxing built into Safari.
Of course, I'm likely to be completely wrong. I remember this being brought up back when the Webkit/Blink fork happen, and in my recent brief search I haven't been able to find any sources again.
No, that's actually pretty much backwards. Chromium believed the sandboxing should happen at the browser level, with WebKit communicating to the trusted chrome process via the "WebKit port" named "chromium", which is basically just a set of IPC hooks that expect to be talking to Chromium on the other side. WebKit2 was designed to bring both the trusted and untrusted parts of the project under the WebKit umbrella, and as a result it had tighter integration.
The Blink fork has made this less of an issue, since now chrome and content code are under single repositories (Chromium and WebKit) in both projects. However, you still see evidence of this all over the place. For example, Blink's content code largely follows WebKit coding style as opposed to the chrome code which follows Google's corporate style, while WebKit's coding style is unified for both chrome and content.
Off-topic to the issue at hand, but I am curious: would Servo[1], the browser engine written in Rust be having lesser (chances of) issues like this? I have written very little Rust, but it seems that the above issues are extremely unlikely to occur with Rust.
[1]: https://servo.org/
Others are still possible and might be just as bad.
I've seen buffer overflows in Java, too. It's immune to writing past the end of the arrays, but it's not immune to, say, smart programmers using one large array to hold multiple buffers that they manually manage, because who knows when the GC kicks in and wrecks havoc. Python may be immune to use-after-frees, but the OpenGL bindings that it calls through the FFI aren't.
To err is human, and languages like Rust don't make it less likely to err, they just give you new opportunities to do it.
Moving to a safe language like Rust would help, absolutely, but to a far lesser degree than people hope. It would close far fewer cans of worms than the hive mind hopes, and it's so new no one really knows how big its own can of worms is.
It doesn't make the person less likely to err overall, but it makes it less likely that those errors get compiled and released.
Not to mention errors stemming from our own arrogance and short-sightedness, which no language can ever protect us against.
The only RCE classes unique to memory-safe languages that come to mind are, like, dynamic deserialization vulnerabilities (like the Rails one) and remote includes (like PHP). Neither of these are applicable to Rust.
Those "errors", by and large, do not result in security problems (especially remote code execution), whereas the problems in C largely do. For example, Rust does introduce a new category of error, "Option.unwrap() failed". But so what? Option.unwrap() is security irrelevant.
That's completely false as stated. Memory safety vulnerabilities are far, far less common in Python (say) than Java. You may have seen buffer overflows in Java, but they're extremely rare in comparison.
You're falling to the "black and white security" fallacy: the belief that if you can't solve a security problem 100% it's not worth solving it at all. In reality, a 99% solution is extremely valuable and in fact almost always the best you can do.
> Moving to a safe language like Rust would help, absolutely, but to a far lesser degree than people hope. It would close far fewer cans of worms than the hive mind hopes, and it's so new no one really knows how big its own can of worms is.
That's very philosophical, but go look at the list of vulnerabilities. Count how many are straightforward memory safety problems: http://webkitgtk.org/security/WSA-2015-0002.html
It's the vast majority, of course. Memory safe languages don't eliminate all security vulnerabilities. But they do reduce their quantity dramatically.
That would mean you have a smaller problem. Fewer vulns, fewer reasons to have security updates.
But it's unlikely that Servo will have no vulns at all. There are classes of bugs (e.g. logic vulns) that are unlikely to have any "generic" strategy to beat them. So you still need a working process to deliver security fixes to the user.
"This seems to me like a good reason for application maintainers to carefully test the updates"
Doesn't seem remotely feasible. Every security release should be manually QA'd by the distribution? If they are already worried enough not to take such updates, I doubt they have the manpower to cover everything not covered by integration tests (a lot?).
I supposed not, it just adds something else that needs to be maintained :P
And as the post makes clear, the security upgrades doesn't even help that much because the original WebKitGTK+ API isn't receiving them anymore and moving to the new API requires massive changes that distros certainly can't ship in an update to a stable release. Apparently they gave applications "a full year to upgrade", which is shorter than the lifespan of distro releases and not realistic given that it requires upgrading to GTK+ 3 and more major changes on top of that. Just the GTK+ 3 switch alone is a multi-year project for complex software, and not helped by the fact they keep breaking their API in new versions. Case in point: https://bugzilla.gnome.org/show_bug.cgi?id=757503
Its a self perpetuating cycle.