Ubuntu 26.10 finishes what 26.04 started: GNU coreutils is now opt-in
Published by RodHat

Ubuntu shipped the 26.10 beta this week. Buried in the release notes is the coreutils
story: cp, mv, and rm have finally crossed from GNU to uutils. Ubuntu 26.10
ships 100% Rust-based coreutils. GNU coreutils ships as an opt-in package. That is a
first for a major distribution, and it is a bigger structural shift than the headline
numbers suggest.
Why cp, mv, and rm took longer
The uutils migration started in earnest with Ubuntu 25.10. Most utilities moved over
without incident. Three did not: cp, mv, and rm. Canonical held them at GNU for
the 26.04 LTS cycle because the uutils implementations had unresolved TOCTOU
(time-of-check/time-of-use) race conditions.
If you are not familiar: when cp or mv moves a file, it checks permissions, checks
the target path, then acts. Between check and act, the filesystem state can change.
An attacker who can manipulate that window can redirect the operation somewhere
unintended. Running rm -rf as root with a vulnerable implementation is the obvious
worst case, and the classic symlink-swap attacks against it are decades old.
The GNU implementations have accumulated workarounds for the obvious cases over thirty years. Some edge cases are still there because nobody wrote the working exploit against a patched system and filed a bug. The uutils implementations got systematic review earlier in their lifecycle, which found the gaps before they calcified into folklore. The 0.8.0 development cycle addressed the remaining race conditions. 26.04 shipped GNU on purpose; 26.10 does not.
What the audit found
Before uutils 0.8.0 landed in 26.04, the project ran an independent security audit. The results: 113 issues, 41 CVEs assigned.
That number is already being quoted by people who want it to mean different things. The “Rust is not a security guarantee” crowd is using it as a gotcha. The uutils boosters are quietly not mentioning it.
Both reactions are wrong. A young codebase that got audited before a major distribution shipped it caught 41 vulnerabilities, nearly all fixed before general availability. That is the audit doing exactly what it should. For comparison, GNU coreutils has not had a comparable systematic audit of the full toolchain. It has had individual CVEs filed against it over thirty years without anyone reviewing the whole thing as a unit. Knowing what your bugs are is unambiguously better than not knowing. The ratio is not the interesting number. The fact that a community project running fast enough to ship in an LTS still stopped to audit is.
GNU becoming opt-in
The actual change in 26.10 is structural. GNU coreutils is no longer the default on
Ubuntu; you pull it in explicitly if you want it. The transition is reversible. Nothing
in the package ecosystem hard-depends on which cp is in /usr/bin/cp. Canonical has
been tracking compatibility gaps upstream and filing issues for anything that diverges
from GNU behavior in the common cases.
For the vast majority of Ubuntu users, this is invisible. cp copies files. mv moves
them. rm removes them. The edge cases where uutils and GNU part ways, mostly around
how certain flags interact with symlinks and hard links, are documented.
What matters more is what this signals about the assumed Linux+GNU coupling. The default userland on the largest Linux distribution is no longer GNU. The kernel’s memory-safety push and Rust landing in the kernel proper got most of the coverage. The coreutils shift is quieter and, in some ways, more concrete: it changes what ships by default on more systems than any kernel change reaches in a release cycle.
Rod runs FreeBSD, where none of this applies directly. The BSD userland is its own thing and has been for fifty years. But watching a major Linux distro make the GNU toolchain optional rather than foundational is a real event. The assumption that Linux and GNU were effectively one thing, operationally if not technically, has been eroding for a few years. Ubuntu just put the heaviest piece on the opt-in shelf.
The part that would have surprised me five years ago is not the Rust. It is the 41 CVEs found and fixed before the code shipped to a billion desktops. That is more process discipline than I expected from a community project moving at this pace. I reserve the right to change that view when the production bug reports land.