Hacker News new | ask | show | jobs
by MaxBarraclough 1892 days ago
I'm less optimistic. Even major C++ projects that do everything right, still have issues that would have been prevented had they used a safe language. My go-to example is Chromium.
2 comments

Rust doesn't prevents logical bugs. Chromium had plenty of those. Most are capable of RCE. They were more dangerous than memory ones because they bypass sandbox in one-click.

As for Windows, The Russians exploited a logical bug in kernel for privilege escalation.

Rust also doesn't prevents overflows, DoS, UaF, OOB.

For example, see CVE-2018-1000657

Another dangerous thing about Rust is Crates. Crates doesn't audit packages for malware and you will face far worse than NPM like situation in future.

> Rust doesn't prevents logical bugs. Chromium had plenty of those.

Right, but that's not the goalpost we're discussing. We're talking about languages that can guarantee safety - the absence of undefined behaviour - not languages that can fully guarantee correctness (e.g. SPARK).

> Rust also doesn't prevents overflows, DoS, UaF, OOB.

In Rust, integer overflow does not cause undefined behaviour. In Safe Rust, undefined behaviour cannot arise from buffer overflows, use-after-free, or out-of-bounds array access. Safe Rust precludes all undefined behaviour, after all. Unsafe Rust may be 'more safe' than C++ in degree, but not in category: it's an unsafe language, as you say.

> Another dangerous thing about Rust is Crates.

Again, sure.

> integer overflow does not cause undefined behavior

Source please?

I ask this since Rust doesn't have a formal specification and I can't keep up with it's inner changes.

It did cause undefined behavior in my case but that was 4 years ago.

It wasn’t undefined behavior four years ago either. RFC 560, from 2014, defines this behavior. As far as I can recall, this was mostly a codification of what was already in place; I’m pretty sure it was never UB.
Here's a source. [0] In release builds, overflow results in two's complement wrapping. In debug builds, it results in a panic at runtime. It never results in undefined behaviour.

Safe Rust really is a safe language. That's really what's remarkable about Rust: it has high ambitions for safety and usability and performance, and it's succeeding in achieving them.

(I hear there are some who want to dilute the safety guarantees of Safe Rust. I'm optimistic that they will continue to be ignored.)

[0] https://doc.rust-lang.org/book/ch03-02-data-types.html#integ...

> Relying on integer overflow’s wrapping behavior is considered an error

Your doc also says this.

> I hear there are some who want to dilute the safety guarantees of Safe Rust

Unfortunately, I don't use Rust at work. I can't talk about it anymore, either. I can't use an informal reference to reason about its actual behavior. At the end of the day, C++ puts food on the table. I try to improve C++ as much as possible, knowing that it is an imperfect language. C++ is heading into safe direction, and I'm sure C++26 will be able to provide more features to write code safely.

Rust seriously need to add Function Overloading, Generics.

> I can't use an informal reference to reason about its actual behavior.

I don't follow here. You can do that. There's a more formal reference too though. [0]

> Relying on integer overflow’s wrapping behavior is considered an error

Good point, I'd missed that. So, Rust strongly discourages relying on the wrapping behaviour of release builds. It seems to take the opposite approach that Java uses.

In Java, you get wrapping arithmetic 'by default' (i.e. when using the arithmetic operators), and there are special functions that give throw-on-overflow behaviour (which almost no one uses). [1] In Rust, the arithmetic operators handle overflow either by wrapping or by panic, depending on build configuration, and if you deliberately want to overflow, there are special functions for that (i32::wrapping_add) which behave identically on Debug and Release builds.

I believe Ada does something similar.

> At the end of the day, C++ puts food on the table. I try to improve C++ as much as possible, knowing that it is an imperfect language.

Sure, I use C++ too. I really only know about Rust from a distance, I'm not a Rust programmer. C++ still has considerable advantages: excellent first-class support on all major platforms, a wealth of libraries available, mature tooling (static analysis, dynamic analysis, top-notch IDEs). Of course, some major software frameworks are natively C++, so you're strongly encouraged to stick with C++ (Qt, Direct3D).

> C++ is heading into safe direction, and I'm sure C++26 will be able to provide more features to write code safely.

The C-style footguns will probably still be there in 20 years. Yes, they've given us std::vector and std::array which allow us to manage arrays more safely than raw C arrays, but read-before-write is still undefined behaviour, dereferencing null is still undefined behaviour, divide-by-zero is still undefined behaviour. They gladly add more functionality to the standard library, but they're very reluctant to tweak the core of the language. At least we have two's complement guaranteed by the C++ standard now.

> Rust seriously need to add Function Overloading, Generics.

I wasn't aware Rust lacked generics. That sounds frustrating.

I have mixed feelings on function overloading. It makes it harder to reason about what function is being called.

[0] https://doc.rust-lang.org/reference/behavior-not-considered-...

[1] https://docs.oracle.com/en/java/javase/16/docs/api/java.base...

Agreed, I keep reaching for C++, because of the dependency many ecosystems have.

Chromium is a good example actually, I bet they would rather follow the "Custom C++ libraries" and "Hardware mitigations" than the Firefox approach.

https://www.chromium.org/Home/chromium-security/memory-safet...

Apple did something similar recently, their iBoot firmware uses a custom safe C dialect.

Thanks, I'd not seen that page before.

> The Chromium project finds that around 70% of our serious security bugs are memory safety problems.

I'll point to this next time this topic crops up.