Skip to main content

Ubuntu 26.10 Replaces cp, mv and rm With Rust Coreutils

·2140 words·11 mins
Ubuntu Rust Coreutils Linux Uutils DevOps Linux Security System Administration
Table of Contents

Ubuntu 26.10 Replaces cp, mv and rm With Rust Coreutils

Ubuntu 26.10 is completing a major change to one of the oldest layers of its Linux user space: the default core utilities are moving entirely from GNU coreutils to the Rust-based uutils implementation.

The final three holdoutsβ€”cp, mv, and rmβ€”were deliberately kept on their GNU implementations for Ubuntu 26.04 LTS because of compatibility and security concerns. Ubuntu’s 26.10 release notes now state that those remaining utilities have been migrated, bringing the default Rust coreutils transition to 100%.

For normal terminal usage, the change should be largely invisible. The commands remain familiar, and uutils is designed to provide GNU-compatible behavior. For developers, system administrators, CI engineers, and maintainers of filesystem-heavy automation, however, the executable underneath those commands is changing.

The migration is also a useful case study in the limits of memory-safe systems programming. Rust eliminates many classes of memory-safety bugs, but it does not automatically eliminate filesystem race conditions, symbolic-link hazards, privilege-boundary mistakes, or compatibility regressions.

πŸ¦€ Ubuntu’s Rust Coreutils Migration Reaches 100%
#

Canonical has been moving Ubuntu’s foundational command-line utilities to uutils, a Rust implementation intended to provide compatible replacements for GNU coreutils.

The transition has been deliberately staged across multiple Ubuntu releases.

Ubuntu 25.10 started the default migration
#

Ubuntu 25.10 made Rust coreutils the default for a broad set of standard utilities. Commands such as ls, cat, chmod, and du moved to the Rust implementation, while the most sensitive filesystem utilities remained on GNU coreutils.

The same release also adopted the Rust implementation of sudo, giving Canonical a broader opportunity to evaluate Rust-based replacements for foundational system software.

Ubuntu 26.04 LTS retained GNU cp, mv and rm
#

Ubuntu 26.04 LTS did not complete the migration.

cp, mv, and rm were retained as GNU implementations because security and compatibility issues in the corresponding uutils implementations still required additional work.

That decision was particularly significant for an LTS release, where stability and long-term compatibility take precedence over completing a migration on an aggressive schedule.

Ubuntu 26.10 completes the transition
#

Ubuntu’s current 26.10 release notes explicitly list 100% Rust coreutils under Ubuntu Foundations and state that the remaining GNU utilitiesβ€”cp, mv, and rmβ€”have now been migrated.

The change means commands such as:

cp source.txt destination.txt
mv old-name new-name
rm obsolete-file

will use the Rust-based implementations under the standard Ubuntu 26.10 configuration.

The command-line interface is not being redesigned. The objective of uutils is compatibility with GNU coreutils, and the project continues to add GNU compatibility fixes as differences are discovered. Recent releases, for example, include fixes for cp, mv, and rm behavior, along with continued security hardening.

πŸ” Why cp, mv and rm Were Delayed
#

The final three utilities were more difficult to migrate than many of the earlier commands because they directly manipulate filesystem state.

Recursive copying and deletion, symbolic-link resolution, ownership preservation, cross-filesystem moves, and privileged operations all introduce subtle security and compatibility requirements.

Security auditing exposed filesystem risks
#

Canonical commissioned security firm Zellic to audit the uutils codebase, with the audit work focusing on security-sensitive utilities.

The resulting findings included multiple issues involving filesystem semantics and TOCTOU behavior. Those problems contributed to Canonical’s decision to retain GNU cp, mv, and rm for Ubuntu 26.04 LTS rather than completing the migration before the LTS release.

The important technical point is that rewriting a utility in Rust does not automatically make its filesystem logic secure.

Rust’s ownership and borrowing model can prevent memory errors such as use-after-free and many forms of buffer-related corruption. It cannot, by itself, prove that a sequence of filesystem operations is safe against concurrent changes.

TOCTOU is a filesystem race problem
#

TOCTOU stands for Time-of-Check to Time-of-Use.

The basic pattern is straightforward:

  1. A program checks whether a filesystem object is safe.
  2. Another process changes the filesystem state.
  3. The original program performs an operation using the result of its earlier check.

If the object changes between steps two and three, the program may operate on something different from what it originally validated.

This is particularly dangerous for recursive filesystem utilities because attackers may attempt to manipulate directory entries or symbolic links while traversal is in progress.

The vulnerability class is therefore fundamentally different from a conventional memory-safety bug. Rust can remove entire categories of memory corruption while still requiring developers to design filesystem operations carefully.

Symbolic links add another attack surface #

Symbolic links make recursive filesystem operations especially complicated.

A path that appears to refer to one object can resolve somewhere else, and the target can potentially change while a traversal is underway.

Recent uutils development has included specific hardening for these scenarios. The project’s release history documents fixes for rm symlink traversal, cp and mv TOCTOU behavior, and recursive chmod symlink handling.

These fixes illustrate why cp, mv, and rm were treated differently from simpler utilities during Ubuntu’s migration.

πŸ› οΈ The Hardening Work Behind the Migration
#

The final migration required upstream changes that addressed both security vulnerabilities and GNU compatibility gaps.

One major development was a TOCTOU-resistant uucore::safe_copy implementation. The project also introduced file-descriptor-based operations to address TOCTOU issues affecting cp and mv, while rm received additional protection against symlink substitution during recursive deletion.

The work was not limited to security.

Recent uutils releases also document fixes for GNU-compatible option handling, exit codes, error messages, recursive filesystem behavior, and other edge cases. The project reports that many of these issues came from differences between the Rust implementation and established GNU behavior.

This distinction matters for production automation:

Security correctness and behavioral compatibility are separate requirements.

A utility can be memory-safe and resistant to a particular filesystem attack while still breaking a script because an option behaves differently or an error message changes.

βš™οΈ What Changes for Shell Scripts
#

For ordinary interactive usage, the transition should be nearly invisible.

The risk is concentrated in automation that treats GNU coreutils behavior as an implicit API.

Basic commands should remain familiar
#

Common operations such as:

cp a.txt b.txt
mv old.txt new.txt
rm old.txt

retain the familiar interface.

The uutils project explicitly targets GNU-compatible behavior, and its current release work continues to close compatibility gaps.

Avoid parsing human-readable diagnostics
#

One of the easiest ways for a script to become implementation-dependent is to match exact error messages.

A fragile pattern looks like this:

if cp "$src" "$dst" 2>&1 | grep -q "specific GNU error message"; then
    ...
fi

A more robust approach is to rely on exit status:

if ! cp "$src" "$dst"; then
    echo "copy operation failed" >&2
    exit 1
fi

Human-readable diagnostic text is not a stable machine interface unless the utility explicitly documents it as such.

Test recursive filesystem operations
#

Automation deserves additional validation if it relies on:

  • recursive cp;
  • recursive rm;
  • symbolic links;
  • cross-filesystem mv;
  • ownership preservation;
  • permission preservation;
  • filesystem image generation;
  • backup and restoration workflows;
  • privileged execution.

These are precisely the areas where implementation details can affect observable behavior.

Cross-filesystem mv requires special attention
#

A same-filesystem mv can generally be implemented as a filesystem rename, while a cross-filesystem move may require copying the source and deleting it afterward.

Those operations have different failure modes and different atomicity characteristics.

Migration and deployment systems should therefore test cross-filesystem moves explicitly rather than assuming that every mv behaves like an atomic rename.

πŸ§ͺ Four Compatibility Areas to Test
#

The following areas deserve particular attention when validating existing automation against Ubuntu 26.10:

Area Why It Matters Recommended Validation
Diagnostic output GNU and Rust implementations can differ in wording Avoid parsing human-readable errors
Filesystem traversal Recursive operations expose implementation-specific edge cases Test representative directory trees
Symbolic links Path resolution affects security and correctness Test symlink creation, copying and deletion
Cross-filesystem operations mv can switch from rename to copy-and-delete semantics Test production-like filesystem layouts

A script that performs only ordinary single-file copies is unlikely to expose the same problems as a backup system recursively processing millions of files.

🐳 CI/CD and Container Images Need Validation
#

The migration also affects containerized workloads.

An Ubuntu 26.10 container inherits the distribution’s default coreutils implementation. Build systems that implicitly assume GNU behavior should therefore include Ubuntu 26.10 in their compatibility matrix before switching production base images.

A simple environment check can identify the active implementation:

command -v cp
cp --version

command -v mv
mv --version

command -v rm
rm --version

For reproducible build infrastructure, recording this information alongside the base-image version can make implementation changes easier to diagnose.

This is particularly important for pipelines that:

  • build operating-system images;
  • manipulate large directory trees;
  • generate package artifacts;
  • perform filesystem migrations;
  • execute privileged build steps;
  • depend on exact command output.

The objective is not to avoid Rust coreutils. It is to make the implementation change an explicit part of the test environment.

πŸ”„ How to Roll Back to GNU Coreutils
#

Ubuntu retains a mechanism for systems that need the traditional GNU implementation.

System-wide GNU coreutils
#

The Ubuntu packaging transition provides a coreutils-from-gnu package for restoring GNU coreutils where supported:

sudo apt install coreutils-from-gnu --allow-remove-essential

Because coreutils is part of the essential operating-system toolchain, this should be treated as a system-level package transition rather than a routine optional package installation.

Administrators should review the proposed package changes before confirming the transaction, particularly on production systems.

Selective GNU command usage
#

A less disruptive strategy is to keep Rust coreutils as the system default while explicitly invoking GNU implementations for workloads that require them.

For example:

gnucp -a src/ dst/
gnusha256sum large-file.iso

Selective invocation can be useful for legacy automation that has already been validated against GNU coreutils.

It also makes the dependency explicit instead of relying on whichever implementation happens to be the system default.

πŸ“œ The Licensing Difference: GPLv3 vs. MIT
#

The migration changes more than the implementation language.

GNU coreutils uses the GPLv3-or-later licensing model, while uutils coreutils uses the MIT License.

For most Ubuntu users, this does not change how the commands are executed. For distributors, downstream developers, and organizations with software-compliance requirements, however, the licensing distinction can be relevant.

The projects also have substantially different development histories.

GNU coreutils is a mature GNU project with decades of development behind it. uutils is a Rust-native reimplementation whose primary objective is compatibility with the established coreutils interface.

Ubuntu is therefore changing the implementation layer underneath a command-line contract that has become deeply embedded throughout Linux software.

🧭 Rust Is Becoming Part of Ubuntu’s System Infrastructure
#

The coreutils migration is one component of Canonical’s broader effort to introduce memory-safe implementations into foundational system software.

Ubuntu 25.10 began the default coreutils transition, while Ubuntu 26.10 completes it by moving cp, mv, and rm to uutils.

The broader engineering challenge is not simply rewriting C code in Rust.

Canonical and upstream developers must preserve:

  • established command-line semantics;
  • filesystem behavior;
  • security properties;
  • privilege boundaries;
  • compatibility with existing shell scripts;
  • performance characteristics;
  • portability across supported platforms.

The latest uutils releases show that this work remains active, with continuing compatibility fixes, security hardening, performance improvements, and reductions in the amount of unsafe code.

πŸ” What Developers Should Test Before Ubuntu 26.10
#

A focused regression suite is more useful than simply verifying that the commands work for basic cases.

Start with ordinary operations:

cp source destination
mv source destination
rm target

Then test recursive behavior:

cp -a source-tree destination-tree
mv source-tree destination-tree
rm -rf test-tree

Test symbolic links:

ln -s target test-link
cp -a test-link copied-link

Test cross-filesystem behavior using filesystems that reflect the production environment:

mv source /path/on/another/filesystem/

Finally, exercise failure and permission paths:

cp /protected/source /protected/destination
rm /protected/target

For CI, identify the active implementations explicitly:

command -v cp
cp --version

command -v mv
mv --version

command -v rm
rm --version

The goal is to identify hidden assumptions before an Ubuntu 26.10 upgrade changes the executable behind a familiar command.

πŸš€ What Ubuntu’s Rust Coreutils Transition Means
#

Ubuntu 26.10’s migration of cp, mv, and rm to uutils marks the completion of a significant change to the distribution’s foundational user-space tooling. Canonical’s release notes now describe the Rust coreutils migration as 100% complete.

For desktop users and ordinary interactive shell workflows, the commands should remain familiar.

For developers, system administrators, and CI engineers, the more important change is underneath the interface: the default implementation is no longer the traditional GNU coreutils codebase.

That makes compatibility testing especially important for automation involving recursive filesystem operations, symbolic links, cross-filesystem moves, exact diagnostic output, or privileged execution.

The transition also demonstrates an important limitation of memory-safe systems programming. Rust can eliminate broad classes of memory-corruption vulnerabilities, but filesystem races, path-resolution mistakes, privilege-boundary issues, and behavioral compatibility still require careful engineering.

Ubuntu 26.10 therefore represents more than another distribution release. It is a large-scale production test of whether a Rust-based implementation can preserve the semantics expected from some of Linux’s oldest and most deeply embedded command-line tools.

Related

Passwordless SSH on Ubuntu: Secure Setup Guide
·365 words·2 mins
Linux SSH Ubuntu Security DevOps
Ubuntu's 10 Official Flavors Explained: Which One Is Right?
·1732 words·9 mins
Ubuntu Linux GNOME KDE Plasma Xfce Wayland Ubuntu Flavors Open Source
TUXEDO OS Switches from Ubuntu to Debian Testing Over Snap
·2237 words·11 mins
TUXEDO OS Debian Testing Ubuntu Linux KDE Plasma Btrfs Snap Linux Laptops Open Source