Hacker News new | ask | show | jobs
by timewizard 363 days ago
> if it compiles, then it’s correct … or at least, will not contain use-after-free or other memory safety errors

In a language with the `unsafe` construct and effectively no automated tooling to audit the uses of it. You have no guarantee of any significance. You've just slightly changed where the security boundary _might_ lie.

> There is a great amount of software already written in other languages.

Yea. And development of those languages is on going. C++ has improved the memory safety picture quite a bit of the past decade and shows no signs of slowing down. There is no "one size fits all" solution here.

Finally, if memory safety were truly "table stakes" then we would have been using the dozens of memory safe languages that already existed. It should be blindingly obvious that /performance/ is table stakes.

6 comments

    In a language with the `unsafe` construct and effectively no automated tooling to audit the uses of it.
You can forbid using unsafe code with the lints built into rustc: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/bu...

Cargo allows you to apply rustc lints to the entire project, albeit not dependencies (currently). If you want dependencies you need something like cargo-geiger instead. If you find unsafe that way, you can report it to the rust safety dance people, who work with the community to eliminate unsafe in crates.

All of this is worlds ahead of the situation in C++.

OP is wrong that there's no tooling. All the C++ tooling that I'm aware of (e.g. ASAN/UBSAN/MSAN/TSAN) is still available on Rust. Additionally, it has MIRI which can check certain code constructs for defined behavior at the MIR level which, unlike sanitizers, validates that all code is sound according to language rules regardless of what would be run by generated assembly; this validation includes unsafe code which still has to follow the language rules. C/C++ doesn't have anything like that for undefined behavior by the way.

However, if I can apply a nitpicking attitude here that you're applying to their argument about the ease with which unsafe can be kept out of a complex codebase. unsafe is pretty baked into the language because there's either simply convenient constructs that the Rust compiler can't ever prove safely (e.g. doubly-linked list), can't prove safely today (e.g. various accessors like split), or is required for basic operations (e.g. allocating memory). Pretending like you can really forbid unsafe code wholesale in your dependency chain is not practical & this is ignoring soundness bugs within the compiler itself. That doesn't detract from the inherent advantage of safe by default.

I do safety critical code. I would consider banning allocation (e.g. just using Core) or avoiding certain data structures a completely feasible strategy to avoid unsafe if I wanted to exclude it from my safety model. It's what I'm already doing in C++. The difference is that in C++, I can never prove the absence of undefined behavior from any part of the codebase, even if I review every single line. Even if I could, that proof might be invalidated by a single change anywhere.

It's not easy in Rust, but it's possible.

Languages with unsafe don't just change where the security boundary lies. It shrinks the size of the area that the boundary surrounds.

C++ has artificially limited how much it can improve the memory safety picture because of their quite valid dedication to backwards compatibility. This is a totally valid choice on their part but it does mean that C++ is largely out of the running for the kinds of table stakes memory safety stuff the article talks about.

There are dozens of memory safe languages that already exist: Java, Go, Python, C#, Rust, ... And a whole host of other ones I'm not going to bother listing here.

Safe rust is a safe language. Yes, it is built upon unsafe rust. But I still consider Python to be a memory safe language despite it being built on C. I can still trust that my Python code doesn't contain such memory errors. Safe Rust is the same in terms of guarantees. That's all that anyone is claiming.
It is a lot like how you have to trust the core proving kernel in a theorem prover but if you do then you can trust every proof created using it.
https://github.com/CertiCoq/certicoq can prove (most of) itself.
The main problem now is that there isn't a platform that has the tooling or infrastructure to prove, including through formal methods, that they are correct and free from bugs in the spirit of the seL4 project.
That's an extreme take now and maybe uncharitable. The safe parts of rust are simply no comparison to the whole c/c++ world: the tooling is eliminating vast swaths of "easy" errors. Unsafe parts might be comparable if they're calling the same libraries.

Industry is seeing quantifiable improvements, eg: https://thehackernews.com/2024/09/googles-shift-to-rust-prog...

> It should be blindingly obvious that /performance/ is table stakes.

Nah, there's a famous WG21 (the C++ committee) paper named "ABI: Now or Never" which lays out just some of the ever growing performance cost of choices the committee has made to preserve ABI and explains that if this cost is to be considered a price paid for something the committee needs to pick "Never" and if they instead want to stop paying the price they need to pick "Now" and, if as the author suspects, they don't actually care, they should pick neither and C++ should be considered obsolete.

The committee, of course, picked neither, and lots of people who were there have since defended this claiming that this was a false dilemma - they were actually cleverly picking "Later" which that author didn't offer. Each time they've repeated this more time has passed yet they're still no closer to this "Later" ...

> It should be blindingly obvious that /performance/ is table stakes.

I think a big part of it is just inertia.

It's been a very slow learning process trying to undo the "performance at every cost" mantra.