Hacker News new | past | comments | ask | show | jobs | submit login

You're missing the point.

Humans cannot write bug-free software[1]. Then if you're soft has security-related things to do (like credential management etc.) you cannot be sure there won't be a way to bypass it.

But here we're talking almost exclusively about remote execution bugs coming from memory-safety issues, which are indeed preventable. Any managed language does the trick, and if they are not fast enough for your use-case there is Rust. (And, before anyone mentions it, since this isn't some low-level/hardware related thing, you don't need to use unsafe Rust).

Rewrites are costly and take time, but we're talking about the wealthiest company on Earth, and this issues has been around for years so they don't really have an excuse…

[1]: at least without using formal verification tools, which are admittedly not practical enough…




> (And, before anyone mentions it, since this isn't some low-level/hardware related thing, you don't need to use unsafe Rust).

That only makes sense if all your code is in Rust, but I suspect this is not true for foreign libraries, even bulletproof ones. It was my understanding that to convince Rust of their safety, you need blocks of "unsafe" code...or not? For example, if I want to embed Chez Scheme into a Rust program, even safely, I apparently can't do that without "unsafe" code. And that's by no means exclusively a "low-level/hardware related thing".


There is no safe way to code anything, ever.

(Yes people, and Apple should try, but...)


This absolutist statement is basically meaningless.

Taking Rust as an example (use Swift or even Java if that works better for your use-case), we know how to write Rust code that is guaranteed to be free from common classes of bugs that these zero-click attacks exploit.

Yes, we aren't going to get rid of all bugs, yes, zero-click attacks might still be possible once in a while, but we can make it much, much harder and more expensive, and therefore greatly reduce the set of people who have access to such attacks, and reduce their frequency.


we know how to write Rust code that is guaranteed to be free from common classes of bugs that these

No we don't.

You are trying to shift the sands, by saying "But.. this one thing we can do...", except even that isn't true.

If we did, it wouldn't keep happening, year after year, decade after decade.

But even with peer reviews, with people supposedly knowing how, well.. it just keeps happening.

Do you think every occurrence is random chance? Or is it, maybe, just maybe, that humans can't write bug free code?


In practice safe Rust code never causes use-after-free bugs, for example, and UAF bugs are large fraction of exploitable RCE bugs.

Safe Rust code could trigger a compiler bug that leads to use-after-free, or trigger a bug unsafe Rust code (i.e., code explicitly marked "unsafe") that leads to use-after-free; the latter are rare, and the former are even rarer. In practice I've been writing Rust code full time for six years and encountered the latter exactly once, and the former never. In either case the bug would not be in the safe code I wrote.

I'm certainly not claiming that humans can write bug-free code. The claim is that with the right languages you can, in practice, eliminate certain important classes of bugs.


Can you now?

So there will be no human error? And rust will have zero compile time bugs, ever?

I'm not against improvement, but the absurd assumption that anything is safe. Because nothing is.


I guess kind of nihilist conservatism (“why bother changing anything since there's nothing we can do”) may explain why we are in such a bad situation today…


How are you sure there is no bug being unfound in rust itself ?


We don't need to be sure of that. We already have ample evidence that code written in Rust has far fewer vulnerabilities than, say, code written in C.


Quoting from https://forum.nim-lang.org/t/8879#58025

> Someone in the thread said he has 30 years experience in programming, and the only new lang which is really close to C in speed is Rust.

He has a point. Both C and release-mode Rust have minimal runtimes. C gets there with undefined behavior. Rust gets there with a very, very robust language definition that allows the compiler to reject a lot of unsafe practices and make a lot of desirable outcomes safe and relatively convenient.

However, Rust also allows certain behavior that a lot of us consider undesirable; they just define the language so that it's allowed. Take integer overflow, for instance https://github.com/rust-lang/rfcs/blob/26197104b7bb9a5a35db2... . In debug mode, Rust panics on integer overflow. Good. In release mode, it wraps as two's complement. Bad. I mean, it's in the language definition, so fine, but as far as I'm concerned that's about as bad as the C https://stackoverflow.com/a/12335930 and C++ https://stackoverflow.com/a/29235539 language definitions referring to signed integer overflow as undefined behavior.

I assume the Rust developers figure you'll do enough debugging to root out integer overflow happens, and maybe that's true for the average system, but not all! I once had to write a C++ program to compute Hilbert data for polynomial ideals. The data remained relatively small for every ideal that could reasonably be tested in debug mode, since debug mode is much slower, after all. But once I got into release mode and work with larger ideals, I started to encounter strange errors. It took a while to dig into the code, add certain manual inspections and checks; finally I realized that the C++ compiler was wrapping the overflow on 64 bit integers! which is when I realized why several computer algebra systems have gmp https://gmplib.org/ as a dependency.

OK, that's the problem domain; sucks to be me, right? But I wasted a lot of time realizing what the problem was simply because the language designers decided that speed mattered more than correctness. As far as I'm concerned, Rust is repeating the mistake made by C++; they're just dressing it up in a pretty gown and calling it a princess.

This is only one example. So, sure, Rust is about as fast as C, and a lot safer, but a lot of people will pay for that execution boost with errors, and will not realize the cause until they've lost a lot of time digging into it... all to boast, what? a 1% improvement in execution time?

IMHO the better design choice is to make it extremely hard to override those overflow checks. There's a reason Ada has historically been a dominant language in aerospace and transportation controls; they have lots of safety checks, and it's nigh impossible to remove them from production code. (I've tried.) Nim seems more like Ada than Rust in this respect: to eliminate the overflow check, you have to explicitly select the very-well-named --danger option. If only for that reason, Nim will seem slower than Rust to a lot of people who never move outside the safe zone of benchmarks that are designed to test speed rather than safety.

To be fair, once you remove all these ~1% slowdown checks, you get a much higher performance boost. And Rust really is a huge improvement on C/C++ IMHO, with very serious static analysis and a careful language design that isn't encumbered by an attempt to be backwards compatible with C. So if you're willing to make that tradeoff, it's probably a perfectly reasonable choice. Just be aware of the choice you're making.


This is again confusing perfect bug-freedom and memory safety. Rust does guarantee your code won't have bugs (like integer overflow), but it will never lead to memory vulnerabilities (in safe Rust), which means you'll never encounter a remote code execution caused by and integer overflow in Rust.

The key takeaway is the following: Rust programs will contain bugs, but none of those bugs will lead to the kind of crazy vulnerabilities that allow those “zero-click attacks”. Is that perfect? No, but it's an enormous improvement over the status quo.


Wrapping on integer overflow isn't a memory safety bug in Rust. It's often a memory safety bug in C because of how common pointer arithmetic is in C, and the likelihood that the overflowed integer will be used as part of that pointer arithmetic. But pointer arithmetic is so exceedingly uncommon in Rust that I've never seen it done once in my ten years of using it. This is a place where familiarity with C will mislead you regarding accurate risk assessment of Rust code; wrapping overflow isn't in the top 20 things to worry about when auditing Rust code for safety. And if you want the overflow checks even in release mode, it's trivial to enable it permanently. And a future version of Rust reserves the right to upgrade all arithmetic to panicking even in release mode, if hardware ever sufficiently catches up.


You can enable integer overflow checking in Rust release builds. Android does. I think that trend will continue and at some point even become the default.


You can enable Rust's overflow checks in release mode, FYI. Doesn't help the default case, but you can at least choose to do so.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: