mirror of
https://github.com/uutils/coreutils.git
synced 2026-05-06 07:26:38 -04:00
ef5d752282
In `-P` / no-dereference mode, cp now opens the source file with `O_NOFOLLOW`, matching GNU cp. This closes a TOCTOU window where an attacker who can swap the source path between cp's `lstat` check and the subsequent open could redirect the read through a symlink to a sensitive file (e.g. /etc/shadow). With `O_NOFOLLOW` the open fails with `ELOOP` instead. The same flag is propagated to `safe_copy::create_dest_restrictive`, so the destination open also refuses to follow a symlink in no-dereference mode. Without that, an attacker who plants the dest path as a symlink between the caller's check and the open could redirect the truncate (and the subsequent write) to any file the caller has permission to write — the symmetric attack to the source side. With `nofollow=true` the dest open returns `ELOOP` and the victim file is left untouched. `copy_on_write` gains a `nofollow` parameter threaded from `copy_helper`, set to `!options.dereference(source_in_command_line)`. In deref mode the flag is false and behavior is unchanged — cp still follows symlinks, matching GNU. Extends `util/check-safe-traversal.sh` with a cp -P strace check so the invariant is locked in: future changes that drop `O_NOFOLLOW` here will fail the smoke test.