Bugs Rust won't catch
lwhsiao
108 points
32 comments
April 29, 2026
Related Discussions
Found 5 related stories in 76.6ms across 8,303 title embeddings via pgvector HNSW
- Bun Rust rewrite: "codebase fails basic miri checks, allows for UB in safe rust" ndiddy · 380 pts · May 15, 2026 · 59% similar
- An incoherent Rust emschwartz · 160 pts · March 23, 2026 · 57% similar
- Approaching Zero Bugs? wrxd · 11 pts · May 01, 2026 · 55% similar
- The limits of Rust, or why you should probably not follow Amazon and Cloudflare randomint64 · 64 pts · May 13, 2026 · 55% similar
- Rust 1.95.0 caution · 11 pts · April 16, 2026 · 55% similar
Discussion Highlights (13 comments)
wahern
> What’s notable is that all of these bugs landed in a production Rust codebase, written by people who knew what they were doing They knew how to write Rust, but clearly weren't sufficiently experienced with Unix APIs, semantics, and pitfalls. Most of those mistakes are exceedingly amateur from the perspective of long-time GNU coreutils (or BSD or Solaris base) developers, issues that were identified and largely hashed out decades ago, notwithstanding the continued long tail of fixes--mostly just a trickle these days--to the old codebases.
jolt42
I wonder if Rust becomes more popular with AI as Rust can help catch what AI misses, but then if that's the case then what about Haskell, or Lean, or?
Scarbutt
But Google told us Rust can only have 0.2 vulnerabilities per million lines of code.
collinfunk
Hi, I am one of the maintainers of GNU Coreutils. Thanks for the article, it covers some interesting topics. In the little Rust that I have used, I have felt that it is far too easy to write TOCTOU races using std::fs. I hope the standard library gets an API similar to openat eventually. I just want to mention that I disagree with the section titled "Rule: Resolve Paths Before Comparing Them". Generally, it is better to make calls to fstat and compare the st_dev and st_ino. However, that was mentioned in the article. A side effect that seems less often considered is the performance impact. Here is an example in practice: $ mkdir -p $(yes a/ | head -n $((32 * 1024)) | tr -d '\n') $ while cd $(yes a/ | head -n 1024 | tr -d '\n'); do :; done 2>/dev/null $ echo a > file $ time cp file copy real 0m0.010s user 0m0.002s sys 0m0.003s $ time uu_cp file copy real 0m12.857s user 0m0.064s sys 0m12.702s I know people are very unlikely to do something like that in real life. However, GNU software tends to work very hard to avoid arbitrary limits [1]. Also, the larger point still stands, but the article says "The Rust rewrite has shipped zero of these [memory saftey bugs], over a comparable window of activity." However, this is not true [2]. :) [1] https://www.gnu.org/prep/standards/standards.html#Semantics [2] https://github.com/advisories/GHSA-w9vv-q986-vj7x
Analemma_
I know nobody's perfect and I'm not asking for perfection, but these bugs are pretty alarming? It seems like these supposed coreutils replacements are being written by people who don't know anything about Unix, and also didn't even bother looking at the GNU tools they are trying to replace. Or at least didn't have any curiosity about why the GNU tools work the way they do. Otherwise they might've wondered about why things operate on bytes and file descriptors instead of strings and paths. I hate to armchair general, but I clicked on this article expecting subtle race conditions or tricky ambiguous corners of the POSIX standard, and instead found that it seems to be amateur hour in uutils.
rvz
This is what happens when many people hype about a technology that solves a specific class of vulnerabilities, but it is not designed to prevent the others such as logic errors because of human / AI error. Granted, the uutils authors are well experienced in Rust, but it is not enough for a large-scale rewrite like this and you can't assume that it's "secure" because of memory safety. In this case, this post tells us that Unix itself has thousands of gotchas and re-implementing the coreutils in Rust is not a silver bullet and even the bugs Unix (and even the POSIX standard) has are part of the specification, and can be later to be revealed as vulnerabilities in reality.
micheles
> uutils now runs the upstream GNU coreutils test suite against itself in CI. That’s the right scale of defense for this class of bug. That's the minimum, it is absurd that they did not start from that!
slopinthebag
I kind of find it funny how people will criticise Rust for not preventing all bugs, when the alternative languages don't prevent those same bugs nor the bugs rust does catch . If you're comparing Rust to a perfect language that doesn't exist, you should probably also compare your alternative to that perfect language as well right? I'd be interested in a comparison with the amount of bugs and CVE's in GNU coreutils at the start of its lifetime, and compare it with this rewrite. Might be enlightening.
9fwfj9r
So it's basically failing on - necessary atomicity for filesystem operation - annoying path & string encoding - inertia for historical behaviors
fschuett
Thanks for the list. I like these lists, so I can put them into a .md file, then launch "one agent per file" on my codebase and see if they can find anything similar to the mentioned CVEs. Rust won't catch it, but now the agents will.
hombre_fatal
One thing that's hard about rewriting code is that the original code was transformed incrementally over time in response to real world issues only found in production. The code gets silently encumbered with those lessons, and unless they are documented, there's a lot of hidden work that needs to be done before you actually reach parity. TFA is a good list of this exact sort of thing. Before you call people amateur for it, also consider it's one of the most softwarey things about writing software. It was bound to happen unless coreutils had really good technical docs and included tests for these cases that they ignored.
immanuwell
rust promised you memory safety and delivered - but turns out the filesystem doesn't care about your borrow checker, and these 44 cves are the receipt
Joker_vD
> The pattern is always the same. You do one syscall to check something about a path, then another syscall to act on the same path. Between those two calls, an attacker with write access to a parent directory can swap the path component for a symbolic link. The kernel re-resolves the path from scratch on the second call, and the privileged action lands on the attacker’s chosen target. It's actually even worse than that somewhat, because the attacker with write access to a parent directory can mess with hard links as well... sure, it only messes with the regular files themselves but there is basically no mitigations. See e.g. [0] and other posts on the site. [0] https://michael.orlitzky.com/articles/posix_hardlink_heartac...