Hacker News new | ask | show | jobs
by StillBored 1942 days ago
This is true, and I suspect that while Rust has this aura of compiler enforced memory safety, its quite possible that the piles of c/c++ tools which _can_ be enabled and run against C code bases make it generally just as secure in practice when those tools are actually enabled.

The simple classes of bugs enforced by rust, are also caught fairly quickly with any kind of memory sanitizer (valgrind?), combined with static analysis tools (coverty?), and automated code quality standards (misra). Run a CI/Code coverage monitor while looking for for these kinds of errors, and I would bet the results are actually better than plain rust due to the maturity of some of these tools.

2 comments

That's plain wrong. If static analysis was as reliable as rust, why would all these C codebases still be full of buffer overflows and memory errors? The borrow checker is, in effect, a static analysis tool... that requires a lot of annotations from the programmer, and blocks compilation otherwise. The equivalent for C would be to annotate all your functions in some formal language and then run, say, frama-C.

About valgrind or sanitizers: they're runtime, so just like tests they can only show the presence of errors, not their absence. Like dynamic type checking.

The borrow checker is a static analysis tool that is 100% sound, unlike the tools for C/C++
And it only catches a trivial minority of actual security problems, which can occur in a lot more ways than use after free/etc.

IMHO, Rust simply isn't good enough at catching all types of bugs to justify rewrites at this point, and its likely when you look at some of the work being done at the processor manufacturing companies that they don't believe it either.

Consider: https://en.wikichip.org/wiki/arm/mte, https://en.wikipedia.org/wiki/Intel_MPX, and https://lwn.net/Articles/718888/

There are quite a number of these in the pipeline, which make some of what rust does redundant.

Uh, not at all. Rust’s compiler probably catches like half of all bugs that currently lead to security issues in memory-unsafe languages. And the things you mentioned are similar band-aids, not fixes.
The borrow checker is 150% sound, it complains about errors but also complains about a lot of things that could have been perfectly fine in reality. There are plenty of times when multiple mutable references would be perfectly safe for instance.

Valgrind might not catch 100% of errors, but at least what it catches are actual errors I care about.

That's an interesting (and correct!) objection — in stats terms, it's the choice between having false positives (your type checker rejects some valid programs) vs. false negatives (Valgrind didn't catch these cases).

If you're writing safety-critical software though, being forced to restructure your code to satisfy the type checker (which, in this case, is kind of a simple proof assistant) seems like a sane tradeoff.

You're talking about completeness: the borrow checker rejects some valid programs (any type system will do that). Soundness is talking about catching incorrect programs; the borrowck doesn't allow a single invalid program through.
Valgrind is not a static analyzer, You should use some C static analyzers to compare the false positive rate. You can use various dynamic instrumentation based tool to detect other classes of bugs that are not caught by the borrow checker in Rust.
Valgrind only catches the errors that your test suite triggers.