Let's start with this "... Rust does provide essentially complete memory and lifetime safety if you stay within the bounds of safe." Technically true, except for the fine print. In many scenarios you have to use "unsafe", e.g. to get equal performance to C in something as trivial as a matrix transpose or when interfacing to other code (cf. this article) Let's compare this to "It's trivial to write buffer overflows that escape ASAN,". The question is how difficult it is avoid writing such overflows. But by turning this around, you already made a biased and misleading statement. Or "and missing a single violation invalidates the semantic meaning of the entire program (particularly in C++)," again technically true, but a meaningless talking point. The only practical question is whether a violation leads to exploitable bug and and how difficult / costly it is to exploit. This "no semantic meaning" comment completely disregards the reality of mitigation which often are very effective. Continuing with "which means virtually all nontrivial programs in C/C++ have UB somewhere (a point we disagree on)." I actually agree with this, but most UB is irrelevant and easily mitigated, e.g. signed overflow is not an issue at all because you just tell your compiler to turn them into traps. And "only eliminating the biggest cause of safety issues." Memory safety is nowhere even close the biggest cause of safety issues in IT. For example, it is - for me personally - completely irrelevant. I never got hacked by a memory safety issue. There are entirely different things I worry about, which Rust makes harder to deal with, e.g. supply chain security.
We have very different priorities. Because I work on safety critical systems, language semantics are very important in order to enable things like formal executable semantics and certified compilers. When I sign my name to an inspection, the inspection is relative to the language semantics. Things like exploitability and even performance are pretty far down the list of concerns, unless they happen to impact functional safety.
In many scenarios you have to use "unsafe"
I don't agree, because unsafe is a part of the language. It's widely accepted practice in C & C++ to only use carefully chosen subsets of each language and this is enforced with linters and coding guidelines. You can straightforwardly ban unsafe the same way, or review uses more carefully, etc.
The question is how difficult it is avoid writing such overflows.
It's nigh-impossible as far as I can tell. I already use formal methods, sanitizers, testing, static analysis, careful design, valgrind, intensive reviews, MISRA, etc. I can still quickly find new issues by firing up the fuzzer or looking at another team's code. Other large projects like Chrome and Linux have thousands of competent eyes on them and still deal with these issues too. What is everyone missing?
e.g. signed overflow is not an issue at all because you just tell your compiler to turn them into traps.
Leaving aside the unnecessarily hyperbolic point enabling traps for my systems might literally kill someone, traps usually aren't a well supported operational mode. GCC's ftrapv is broken for example, ubsan isn't recommended for production, and GCC doesn't implement ubsan-minimal. MSVC doesn't support overflow traps at all, nor do most certified compilers. "Just use clang" obviously isn't what you're intending here, so I'm unsure how to interpret this.
In regards to memory safety being the biggest issue, I'm referencing the "70% of high severity bugs" numbers that have been put out by Microsoft and the Chrome teams and repeated by CISA in their memory safety roadmaps.
It's great that you haven't experienced large numbers of memory safety issues, but I can only speak to the lived experience of heartbleed and others. I see memory safety issues daily. I don't see supply chain attacks frequently and given how much publicity accompanied the discovery of the XZ attack, I suspect that's true for others.
So you’re using formal methods, sanitizers, the whole gamut of verification and yet you can “quickly” find new issues just by fuzzing. Sounds like there’s some significant problem there that you’re not mentioning.
Microsoft and Google have a ton of legacy code, they need to have high performance because they’re pushing everything to the web in order to spy better on people, they always churn their software and they are a very juicy target. As far as I’m concerned, they should rewrite everything in Rust and stop telling other people what to do.
But of course, they also need to sell Rust to the public, otherwise they would run out of developers or would have to maintain everything themselves. Hence the cheerleading.
This blog post is much closer to the reality of using Rust in production. In fact I’d add a couple of pitfalls myself:
* original cheerleader gets bored of the Rust rewrite/moves on and the project dies.
* original cheerleader moves on and the project lives under maintenance with non-Rust programmers which do not enjoy working on it and delay and reject changes and/or feature requests.
> So you’re using formal methods, sanitizers, the whole gamut of verification and yet you can “quickly” find new issues just by fuzzing. Sounds like there’s some significant problem there that you’re not mentioning.
Or perhaps you're missing the super-text, that all those things were insufficient to make C safe.
The "significant problem" is the same that every other organization faces: the testing and validation isn't quite as good as it could be and I know where to poke.
Maybe adding to the last point: I worry far more that some employee or student in my lab causes a disaster by downloading compromised python package than I get hacked by any memory safety issue. We do not use Rust, but Cargo would also be a massive concern. Rustup helps to destroy decades of user education that you do not download and run scripts from the internet.
I am fully able to appreciate that memory safety is important and Rust stepped up the game in mainstream programming. I think this is cool. But the exclusive and exaggerated focus on this does more harm than good. Memory safety is certainly much more important for advertisement companies such as Google to secure their mobile spying platforms than it is for me. The religious drive to push Rust everywhere to achieve a relatively modest[1] practical improvement in memory safety clearly shows that some part of the community rather naively adopted the priorities of certain tech companies at the cost of other - maybe more relevant - things.
1. I am fully able to understand the 100% guarantees that Rust can provide when sticking to safe Rust are conceptionally a fundamental step forward compared to what C provides out of the box. But this should not be misrepresented as a huge practical step forward to what can be achieved in memory safety already in C/C++ if one cares about it.
You seem to consider convenient dependency management a security hazard, which I have always found to be a pretty weird take. It logically follows that the severe difficulty of managing dependencies in C and C++ projects is actually a security feature, or how else are we supposed to understand this opinion?
Let's not pretend that anything is better on the traditional C/C++ side, where the approach is usually one or more of:
1. Vendoring dependencies in-tree. This can result in security problems from missing out on bugfixes upstream.
2. Reinventing functionality that would otherwise be served by a dependency. This can result in security problems from much less battle-tested, buggy in-house implementation. In closed-source code, this is effectively security by obscurity.
I've seen both of these cause issues in large C++ projects.
For reference, the Rust/Cargo ecosystem contains a lot of tools and infrastructure to address supply-chain security, but it will always be a difficult problem to solve.
Regardless of the programming language it is a security hazard, that is why we have now SBOM in the industry, and many corporations have procedures in place before adding that cool dependency into the project.
Regardless it is cargo, vcpkg/conan, nuget, maven, npm,....
It isn't validated by legal and IT for upload into internal repos, doesn't get used.
The rust language is not well-specified, and if you take rust as the language specified by the compiler, then it has many soundness bugs. So even if you stay within "safe rust", you can segfault.
The "memory safety" of rust is oversold since "safety" is not formally proven for the rust language. While anecdotally memory-related bugs seem less likely, rust without unsafe is not absolutely safe.