Date Bug in Rust-Based Coreutils Affects Ubuntu 25.10 Automatic Updates
Posted3 months agoActive2 months ago
lwn.netTechstoryHigh profile
heatedmixed
Debate
80/100
RustUbuntuCoreutilsSoftware Development
Key topics
Rust
Ubuntu
Coreutils
Software Development
A bug in Rust-based coreutils affects Ubuntu 25.10 automatic updates, sparking debate about the trade-offs of rewriting battle-tested C utilities in Rust.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
50m
Peak period
148
Day 1
Avg / period
32
Comment distribution160 data points
Loading chart...
Based on 160 loaded comments
Key moments
- 01Story posted
Oct 23, 2025 at 4:49 PM EDT
3 months ago
Step 01 - 02First comment
Oct 23, 2025 at 5:38 PM EDT
50m after posting
Step 02 - 03Peak activity
148 comments in Day 1
Hottest window of the conversation
Step 03 - 04Latest activity
Nov 1, 2025 at 7:52 AM EDT
2 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45686919Type: storyLast synced: 11/20/2025, 8:14:16 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
Pros and Cons either way for better or worse depending on your perspective.
Personally while I think Rust is a decent language it would not have caught on with younger devs if C/C++ didn't have such a shitty devex that is stuck 30 years in the past.
Younger people will always be more willing to break things and messing around with ancient and unfriendly build/dev does not attract that demographic because why waste time messing around with the build env that actually getting things done.
One day rust will be the same and the process will start again.
It is so much more fun to cargo-download some stuff and build some new shiny Rust-xyz implementation of Z on your Apple Macbook and even get some HN attention just for this. The problem with all the Rust hype is that people convince themselves that they are actually helping the world by being part of a worthwhile cause to rid the world from old languages, while the main effect is that i draws resources away from much more important efforts and places an even higher burden on the ecosystem - making our main problem - sustainable maintenance of free software - even harder.
What breaking changes has Rust made "on a whim" ?
I don't know about "on a whim", but this isn't far off in regards to breaking compatibility. And it caused some projects, like Nix, a lot of pain.
https://github.com/rust-lang/rust/issues/127343
https://devclass.com/2024/08/19/rust-1-80-0-breaks-existing-...
Probably not the best way to lead, considering that that phrase is the entire root of the disagreement you're chiming in on!
> but this isn't far off in regards to breaking compatibility.
I think it might be worth elaborating on why you think that change "isn't far off" being made "on a whim". At least to me, "on a whim" implies something about intent (or more specifically, the lack thereof) that the existence of negative downstream impacts says nothing about.
If anything, from what I can tell the evidence suggests precisely the opposite - that the breakage wasn't made "on a whim". The change itself [0] doesn't exactly scream "capricious" to me, and the issue was noticed before Rust 1.80.0 released [1]. The libs team discussed said issue before 1.80.0's release [2] and decided (however (un)wisely one may think) that that breakage was acceptable. That there was at least some consideration of the issue basically disqualifies it from being made "on a whim", in my view.
[0]: https://github.com/rust-lang/rust/pull/99969
[1]: https://github.com/rust-lang/rust/issues/127343
[2]: https://github.com/rust-lang/rust/issues/127343#issuecomment...
Your post itself reinforces the OP's claim.
Edit: Seriously. At this point, it seems clear that the culture around Rust, especially driven by proponents like you, indirectly have a negative effect on both Rust software, and software security & quality overall, as seen by the bug discussed in the OP. Without your kind of post, would Ubuntu have felt less pressured to make technical management decisions that allowed for the above bug?
> Your post itself reinforces the OP's claim.
Again, I think it might be worth elaborating precisely what you think "on a whim" means. To me (and I would hope anyone else with a reasonable command of English), making a bad decision is not the same thing as making a decision on a whim, and you have provided no reason to believe the described change falls under the latter category instead of the former.
In C and C++ land, if gcc (as a thought experiment) tried breaking backwards compatibility by changing the language, people would be flabbergasted, complain that gcc made a dialect, and switch to Clang or MSVC or fork gcc. But for Rust, Rust developers just have to suck it up if rustc breaks backwards compatibility. Like Dtolnay's comment in the Github issue I linked indicates. If and once gccrs gets running, that might change.
Though I am beginning to worry, for the specification for Rust gotten from Ferrocene might be both incomplete and basically fake, and that might cause rustc and gccrs to more easily risk becoming separate dialects of Rust, which would be horrible for Rust, and since there should preferably be more viable options in my opinion of systems languages, arguably horrible for the software ecosystem as well. I hope that there are plans for robust ways of preventing dialects of Rust.
More than anything, the Rust community is hyper-fixated on stability and correctness. It is very much the antithesis to “move fast and break things”.
This is incorrect.
https://devclass.com/2024/08/19/rust-1-80-0-breaks-existing-...
Sorry, but your argument is incorrect.
Somebody is attempting to characterize the Rust community in general as being similar to other programming communities that value velocity over stability, such as the JS ecosystem and others.
I’m pointing out that incidents such as this are incredibly rare, and extremely controversial within the community, precisely because people care much more about stability than velocity.
Indeed, the design of the Rust language itself is in so many ways hyper-fixated on correctness and stability - it’s the entire raison d’etre of the language - and this is reflected in the culture.
And your post is itself a part of the Rust community, and it itself is an argument against what you claim in it. If you cannot or will not own up to the 1.80 time crate debacle, or mention the 1.80 time crate debacle proactively as a black mark that weighs on Rust's conscience and that it will take time to rebuild trust and confidence in Rust's stability because of it, well, your priorities, understood as in the Rust community's priorities, are clear, and they do not, in practice, lie with stability, safety and security, nor with being forthcoming.
Cargo always picks the newest version of a dependency, even if that version is incompatible with the version of Rust you have installed.
You're like "build this please", and it's like "hey I helpfully upgraded this module! oh and you can't build this at all, your compiler is too old granddad"
They finally addressed this bug -- optionally (the default is still to break the build at the slightest provocation) -- in January this year (which of course, requires you upgrade your compiler again to at least that)
https://blog.rust-lang.org/2025/01/09/Rust-1.84.0/#cargo-con...
What a bunch of shiny-shiny chasing idiots with a brittle build system. It's designed to ratchet forward your dependencies and throw new bugs and less-well-tested code at you. That's absolutely exhausting. I'm not your guinea pig, I want to build reliable, working systems.
gcc -std=c89 for me please.
Also picking C89 over any later iteration is bananas.
For C++, there is vcpkg and Conan. While they are overall significantly or much worse options than what Rust offers according to many, in large part due to C++'s cruft and backwards compatibility, they do exist.
dnf or apt, depending on if Fedora/EL or Debian...
No it doesn't. What on earth are you talking about?
Sure, some pre-1.0 libraries in Rust land are actually wildly volatile, but I find that's not especially the norm, out of the crates I've used. That said... 0.4 for EIGHT YEARS is also a pretty darn good sign you've solidified the API by now, and should probably just tag a 1.0 finally...
So you seem to be saying "I don't like how Rust libraries communicate their stability." But that's something wholly different from "Ready to make breaking changes on a whim." Yet your commentary doesn't distinguish these concepts and instead conflates them.
And when most library authors communicate "the API is not stabilized, you must be prepared for breaking changes on a whim", then yeah, of course I am going to perceive that as a lack of stability.
Moreover, it's unclear to me if you're aware that, in the Rust ecosystem, 0.x and 0.(x+1) are treated as semver incompatible releases, while 0.x.y and 0.x.(y+1) are treated as semver compatible releases. While the actual semver specification says "Anything MAY change at any time. The public API SHOULD NOT be considered stable." when the major version is 0, this isn't actually true in the Rust crate ecosystem. For example, if you have `log = "0.4"` in your `Cargo.toml`, then running a `cargo update` will only bump you to semver compatible releases without breaking changes (up to a human's ability to adhere to semver).
Stated more succinctly, in the Rust ecosystem, semver breaking changes are communicated by incrementing the leftmost non-zero version component. In other words, you cannot correctly interpret what version numbers mean in the Cargo crate ecosystem using only the official semver specification. You also need to read the Cargo documentation: https://doc.rust-lang.org/cargo/reference/semver.html#change...
(emphasis mine)
> This guide uses the terms “major” and “minor” assuming this relates to a “1.0.0” release or later. Initial development releases starting with “0.y.z” can treat changes in “y” as a major release, and “z” as a minor release. “0.0.z” releases are always major changes. This is because Cargo uses the convention that only changes in the left-most non-zero component are considered incompatible.
So I repeat: you are conflating perception with what actually is reality. This isn't to say that perception is meaningless or doesn't matter or isn't a problem in and of itself. But it is distinct from what is actually happening. That is, "the Rust crate ecosystem doesn't use semver version numbers in a way that can be interpreted using only the official semver specification" is a distinct problem from "the Rust crate ecosystem makes a habit of introducing breaking changes on a whim." They are two distinct concerns and you conflating them is extremely confusing and misleading.
This is a stark difference to back in the early post 1.0 days where many high profile crates needed nightly and everyone was experimenting.
https://devclass.com/2024/08/19/rust-1-80-0-breaks-existing-...
So what's actually your point here?
Did they change the language? GCC is not meant to change the C or C++ languages (unless the user uses some flag to modify the language), there is an ISO standard that they seek to be compliant with. rustc, on the other hand, only somewhat recently got a specification or something from Ferrocene, and that specification looks lackluster and incomplete from when I last skimmed through it. And rustc does not seem to be developed against the official Rust specification.
That's not what you asked though, these were intentional breakages. Language standard or not.
In any case though, bringing up language specification as an example for maturity is such a massive cop-out considering the amount of UB in C and C++. It's not like it gives you good stability or consistency.
> there is an ISO standard that they seek to be compliant with
You can buy RM 8048 from NIST, is that the "culture" of stability you have in mind?
You are completely wrong, and you ought to be able to see that already.
It makes a world of difference if it is a language change or not. As shown in dtolnay's comment https://github.com/rust-lang/rust/issues/127343#issuecomment... .
If breakage is not due to a language change, and the program is fully compliant with the standard, and there is no issue in the standard, then the compiler has a bug and must fix that bug.
If breakage is due to a language change, then even if a program is fully compliant with the previous language version, and the programmer did nothing wrong, then the program is still the one that has a bug. In many language communities, language changes are therefore handled with care and changing the language version is generally set up to be a deliberate action, at least if there would be breakage in backwards compatibility.
I do not see how it would be possible for you not to know that I am completely right about this and that you are completely wrong. For there is absolutely no doubt that that is the case.
> In any case though, bringing up language specification as an example for maturity is such a massive cop-out considering the amount of UB in C and C++.
Rust is worse when unsafe is involved.
https://materialize.com/blog/rust-concurrency-bug-unbounded-...
There are almost no C programs without UB. So a lot of what you would call "compiler bugs" are entirely permitted standard. If you say "no true C program has UB" then of course, congrats, your argument might be in some aspects correct. But that's not really the case in practice and your language standard provides shit in terms of practical stability and cross-compatibility in compilers.
> I do not see how it would be possible for you not to know that I am completely right about this and that you are completely wrong. For there is absolutely no doubt that that is the case.
Lol, lmao even.
> Rust is worse when unsafe is involved.
It's really not.
Good luck achieving anything of long-term value this way.
The core bug seems to be that support for `date -r <file>` wasn't implemented at the time ubuntu integrated it [1, 2].
And the command silently accepted -r before and did nothing (!)
0: https://lwn.net/Articles/1043123/
1: https://github.com/uutils/coreutils/issues/8621
2: https://github.com/uutils/coreutils/pull/8630
I'm frankly appalled that an essential feature such as system updates didn't have an automated test that would catch this issue immediately after uutils was integrated.
Nevermind the fact that this entire replacement of coreutils is done purely out of financial and political rather than technical reasons, and that they're willing to treat their users as guinea pigs. Despicable.
This feels like a large corporation, in the bad sense.
If it was added in bulk, with many other still unsupported option names, why does the program not crash loudly if any such option is used?
A fencepost error is a bug. A double-free is a bug. Accepting an unsupported option and silently ignoring it is not, it takes a deliberate and obviously wrong action.
No, it doesn't. For example, you could have code that recognizes that something "is an option", and silently discards anything that isn't on the recognized list.
That's a deliberate action.
[0]: https://github.com/yuankunzhang/coreutils/commit/850bd9c32d9...
[1]: https://github.com/yuankunzhang/coreutils/blob/88a7fa7adfa04...
> deliberate and wrong decision
Yeah... I hope "we" will not switch to it just because it is written in Rust. There is much more than just the damn language behind it.
I have automated a lot of things executing other utilities as a subprocess and it's absolutely crazy how many utilities handle CLI flags just seemingly correct, but not really.
The last commit[0] is a fix for date parsing to bring it in line with the GNU semantics, which seems like a pretty good candidate.
Edit: Or not, see evil-olive's comment[1] for a more likely candidate.
0: https://github.com/uutils/coreutils/commit/0047c7e66ffb57971...
1: https://news.ycombinator.com/item?id=45687743
https://bugs.launchpad.net/ubuntu/+source/rust-coreutils/+bu...
EDIT: Just to be clear, I'm otherwise perfectly happy that these experiments are being done, and we should all be better off for it and learn something as a result. Obviously somebody has assessed that this tradeoff has at least a decent probability of being a net positive here in some timeframe, and if others are unhappy about it then I suppose they're welcome to install another implementation of coreutils, or use a different distro, or write their own, or whatever.
F.ex. `sudo-rs` does not support most of what the normal `sudo` does... and it turned out that most people did not need most of `sudo` in the first place.
Less code leads to less bugs.
Hence "doas".
OpenBSD has a lot of new stuff throughout the codebase.
No need for adding a bloated dependency (e.g. Rust) just because you want to re-implement "yes" in a "memory-safe language" when you probably have no reasons to.
As an obvious example, I sometimes download files from the Internet, then run coreutils sha256sum or the like on those files to verify that they're trustworthy. That means they're untrusted at the time where I use them as input to sha256sum.
If there's an RCE in sha256sum (unlikely, but this is a thought experiment to demonstrate an attack vector), then that untrusted file can just exploit that RCE directly.
If there's a bug in sha256sum which allows a malicious file to manipulate the result, then a malicious file could potentially make itself look like a trusted file and therefore get past a security barrier.
Maybe there's no bug in sha256sum, but I need to base64 decode the file before running sha256sum on it, using the base64 tool from coreutils.
If you use your imagination, I'm sure you yourself can think up plenty more use cases where you might run a program from GNU coreutils against untrusted user input. If it helps, here's a Wikipedia article which lists all commands from GNU coreutils: https://en.wikipedia.org/wiki/GNU_Core_Utilities#Commands
EDIT: To be clear, this comment is only intended to explain what the attack surface is, not to weigh in on whether rewriting the tools in Rust improves security. One could argue that it's more likely that the freshly rewritten sha256sum from uutils has a bug than that GNU sha256sum has a bug. The statement "tools from coreutils are sometimes used to operate on untrusted input and therefore have an attack surface worth exploring" is not the same as the statement "rewriting coreutils in Rust improves security". Personally, I'm excited for the uutils stuff, but not primarily because I believe it alone will directly result in significant security improvements in Ubuntu 25.10.
Rust is not a silver bullet.
Honestly, Rust-related hilarity aside, this project was a terrible, terrible idea. Unix shell environments have always been ad hoc and poorly tested, and anything that impacts compatibility is going to break historical code that may literally be decades old.
See also the recent insanity of GNU grep suddenly tossing an error when invoked as "fgrep". You just don't do that folks.
The 'fgrep' and 'egrep' didn't throw errors, it would just send a warning to standard error before behaving as expected.
Those commands were never standardized, and everyone is better off using 'grep -F' and 'grep -E' respectively.
Noted without comment. Except to say that I've had multiple scripts of my own break via "just" discovering garbage in the output streams.
> Those commands were never standardized
"Those commands" were present in v7 unix in 1979!
The only place that that doesn't support 'grep -E' and 'grep -F' nowadays is Solaris 10. But if you are still using that you will certainly run into many other missing options.
[1] https://pubs.opengroup.org/onlinepubs/007908775/xcu/egrep.ht... [2] https://pubs.opengroup.org/onlinepubs/007908775/xcu/fgrep.ht...
Why?
It's surely not. The question wasn't how to rewrite the shell environment to be more "endorseable", though.
The point is that we have a half century (!) long history of writing code to this admittedly fragile environment, with no way to audit usage or even find all the existing code (literally many of the authors are retired or dead).
So... it's just not a good place to play games with "Look Ma, I rewrote /usr/bin/date and it's safe now!" Mess with your own new environments, not the ones that run the rest of the world please.
Sounds like a plan. Let me know when you're done, and then we can remove fgrep.
In sort command
Is this the best they could come up with?
But the worst you can do is crash 'sort' with that. Note that uutils also has crashes. Here is one due to unbounded recursion:
Not saying that both issues don't deserve fixing. But I wouldn't really panic over either of them.[1] https://lwn.net/Articles/535735/
The thought of rewriting anything as intricate, foundational, and battle-tested as GNU coreutils from scratch scares me. Maybe I'd try it with a mature automatic C-to-Rust translator, but I would still expect years of incompatibilities and reintroduced bugs.
See also the "cascade of attention-deficit teenagers" development model.
It is extremely bad that it's not a relatively straightforward process for any random programmer to rewrite coreutils from scratch as a several week project. That means that the correct behavior of coreutils is not specified well enough and and it's not easy enough to understand it by reading the source code.
For a business it's often fine to stop at a local maximum, they can keep using old versions of coreutils however long they want, and they can still make lots of money there! However we are not talking about a business but a fundamental open source building block that will be around for a very long time. In this setting continuous long term improvement is much more valuable than short term stability. Obviously you don't want to knowingly break stability either, and in this regard I do think Ubuntu's timeline for actually replacing the default coreutils implementation is too ambitious, but that's beside the point—the rewrite itself is valuable regardless of what Ubuntu is doing!
[0]: https://news.ycombinator.com/item?id=38853429
Perhaps it is also so they can be used in closed source systems (I have uutils installed on my Windows system which works nicely).
https://buildings.honeywell.com/au/en/products/by-category/b...
The reasoning was that the users didn’t own the device. While I personally believe this is not consistent with recent interpretations of the license by the courts, I think they concluded that it was worth the risk of a customer suing to get the source code, as the company could then pull the hardware and leave that customer high and dry. It is unlikely any of their users a would risk that outcome.
[0]: https://ubuntu.com/pro/
Edited to add: it would be cool if, instead of the top-most wealth-concentrators F[500:], there was an index of the top-most wealth-spreaders F[:500]. What would that look like? A list of cooperatives?
https://sfconservancy.org/blog/2021/mar/25/install-gplv2/ https://sfconservancy.org/blog/2021/jul/23/tivoization-and-t... https://events19.linuxfoundation.org/wp-content/uploads/2017...
https://sfconservancy.org/copyleft-compliance/vizio.html
https://packages.ubuntu.com/plucky/rust-coreutils
The dependencies of rust-coreutils list libgcc-s1, which is GPL version 3.
However, it would be a fairly straightforward project to replace the unwinder used directly by Rust binaries with the one from libunwind. Given that this hasn't happened, I'd be surprised if Canonical is actually investing into a migration. Of course there are much bigger tasks for avoiding GPLv3 software, such as porting the distribution (including LLVM itself and its users) from libstdc++ (GCC's C++ standard library that requires GCC to build, but provides support for Clang as well) to libc++ (LLVM's C++ standard library).
Assuming this theory is true then, what other GPLv3-licensed "core" software in the distro could be next on their list?
- GNU coreutils (GPLv3)
- uutils coreutils (MIT)
- busybox (GPLv2)
https://en.wikipedia.org/wiki/Toybox
Brave of them to ship a Rust port of sudo as well.
309 more comments available on Hacker News