Commit Graph

333 Commits

Author SHA1 Message Date
Sylvestre Ledru bd170a5d4b cp: strip setuid/setgid when chown fails during -p (#9750)
When `cp -p` cannot chown the destination to the source's owner
(e.g. a non-root user copying a root-owned setuid file), GNU cp
strips the setuid and setgid bits from the applied mode so the
destination does not give the copying user elevated privileges via
the copy. uutils was unconditionally applying the source mode,
producing user-owned files with a live setuid bit.

Track `ownership_preserved` alongside the existing chown retry
logic and, in the subsequent `handle_preserve(mode, ...)` block,
mask off `0o6000` from the source's mode when ownership could not
be preserved. The sticky bit (01000) is kept, matching GNU.
2026-05-06 11:47:38 +02:00
Sylvestre Ledru 7ba1bf857c cp: don't preserve xattrs with -p by default (#9704)
GNU `cp -p` preserves mode, ownership, and timestamps. xattrs are
NOT preserved unless the user asks for them via `--preserve=xattr`
or `-a`. uutils's `Attributes::DEFAULT` had xattr set to
`Preserve::Yes { required: true }`, which (1) diverges from GNU and
breaks scripts that expect the stock behavior, (2) leaks security
xattrs like file capabilities and SELinux labels into copies when
run as root, and (3) fails hard on destinations that don't support
xattrs.

Remove the xattr override in `Attributes::DEFAULT` so it inherits
`Preserve::No` from `Attributes::NONE`. `Attributes::ALL` (used by
`-a` and `--preserve=all`) still sets xattr to Yes, and
`--preserve=xattr` still works as before.
2026-05-06 11:47:38 +02:00
Sylvestre Ledru ef5d752282 cp: open source and dest with O_NOFOLLOW in no-dereference mode (#10017)
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.
2026-05-06 11:47:38 +02:00
Sylvestre Ledru 681030bca3 cp: create destination with restrictive 0o600 initial mode (#10011)
cp previously created the destination with mode 0o666 masked by umask
(typically 0o644), then later applied the final permissions via
set_permissions. In a shared directory like /tmp this opened an
observable window where another user could open the destination with
the intermediate broad mode before cp narrowed it, leaking file
contents that were intended to stay private.

Create dest with 0o600 initially in every non-symlink code path —
clone, sparse_copy, sparse_copy_without_hole, fs_copy, the stream
path, and the non-Linux fs::copy fallback. The existing
set_permissions call in copy_file applies the real final mode after
the content is written, so user-visible end state is unchanged; only
the intermediate mode is tightened. Matches GNU cp.

Extend `util/check-safe-traversal.sh` with a cp strace check that
asserts the destination openat carries mode 0600 so a future change
that reintroduces 0666 fails the smoke test.
2026-05-06 11:47:38 +02:00
Babur Ayanlar 8bff321cfb fix(cp): always create dest dirs with owner write bit before fixing permissions 2026-03-17 18:33:17 +01:00
Victor Prokhorov e6a3bb596f cp: handle special files (#11163) 2026-03-05 00:01:52 +01:00
Avi Weinstock 2a81c11344 Merge pull request #11148 from Zellic/cp-fix-nonutf8-panic
cp: Fix panic when recursively copying a directory with a non-UTF8 name
2026-02-28 09:26:02 +01:00
Christopher Dryden 42b734bc42 Fix failing SELinux cp tests 2026-02-15 22:07:40 +01:00
Christopher Dryden 102c94fa78 cp: fix SELinux context handling for cp-a-selinux GNU test 2026-02-15 22:07:40 +01:00
Nikola Lukovic 31c5102bee cp: fix recursive copy of readonly directories (#10529)
Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
2026-02-07 14:28:24 +01:00
Yuri Astrakhan 05204864d6 refactor: inline format! args in a few places (#10730)
* refactor: inline format! args in a few places

* in one spot remove redundant mem alloc

* run clippy fix with mixed
2026-02-07 10:05:44 +01:00
✿ Fleur de Blue 2a2cafdbd4 Re-enable unused_qualifications lint (#10571) 2026-02-03 21:55:21 +01:00
Chris Dryden 525d1f88ec cp/mv: suppress xattr ENOTSUP errors for optional preservation (#10083)
* cp/mv: suppress xattr ENOTSUP errors for optional preservation

* mv: copy xattrs for symlink fallback and format tests

* cp: fix test expectation for GNU-compatible error format

* fix test portability for Android and xattr detection

---------

Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
2026-01-18 22:42:14 +01:00
Max Ambaum 2a044db3a2 cp: Fixed POSIXLY_CORRECT test to actually check if file exists and its contents (#10247)
cp: Added check of file contents in POSIXLY_CORRECT test

cp: Fixed windows test by including path

cp: Updated test
2026-01-17 04:41:29 -08:00
oech3 25c088154a cp: Avoid other error at cp stream /dev/full 2026-01-09 20:09:19 +09:00
Phan Trung Thanh 7274e7f6a1 cp: set status code when encountering circular symbolic links (#9757)
* cp: set exit code when encountering circular symbolic links error when copying directory

* cp: add test to ensure that cp sets the status code when encountering circular symbolic links during directory copy

* cp: check that the output of circular symbolic link test has the correct message

* cp: update check for stderr message

* cp: update circular symbolic link test to account for directory format in windows

* cp: use std::path::MAIN_SEPARATOR_STR for test
2026-01-06 10:51:26 +01:00
max-amb 83a52bf561 cp: Added test for permissions copying to an existing file 2026-01-04 13:18:48 +00:00
Dylan Skelly 9cf774bed8 cp: symlink flags fixing conflicting flag logic to use last flag (#9960)
* Adding overrides_with_all for symlink flags for ordering

* Adding regression tests for symlink flag ordering
2026-01-01 15:04:47 +01:00
RustyJack 939ab037a2 uucore: use --suffix to enable backup mode (#9741) 2025-12-21 10:17:35 +01:00
Cả thế giới là Rust 415d01cc75 cp: add readonly file regression tests (#9045)
* feat: add comprehensive readonly file regression tests for cp

- Add 10 new test functions covering readonly destination behavior
- Tests cover basic readonly copying, flag combinations, and edge cases
- Include macOS-specific clonefile behavior tests
- Ensure readonly file protection from PR #5261 cannot regress
- Tests provide evidence for closing issue #5349

* perf: optimize readonly regression tests with batched I/O operations

- Reduce file I/O overhead by batching file operations
- Consolidate setup operations to minimize system calls
- Improve test execution time from 0.44s to 0.27s (38% improvement)
- Maintain comprehensive test coverage for readonly file behavior

* fix: remove duplicate tests and trivial comments per PR feedback

- Remove test_cp_readonly_dest_regression (duplicate of test_cp_dest_no_permissions)
- Remove test_cp_readonly_dest_with_force (duplicate of test_cp_arg_force)
- Remove test_cp_readonly_dest_with_remove_destination (duplicate of test_cp_arg_remove_destination)
- Remove test_cp_macos_clonefile_readonly (duplicate of test_cp_existing_target)
- Remove test_cp_normal_copy_still_works (duplicate of test_cp_existing_target)
- Remove trivial performance comments from readonly tests
- Keep existing proven tests per maintainer preferences
- Keep unique readonly tests that provide additional coverage
2025-12-10 14:54:17 +01:00
Chris Dryden 1ffad8228a cp: Enabling cp force flag to run on windows (#9624)
* Enabling cp force flag to run on windows

* Windows requires clearing the readonly permissions before deleting
2025-12-10 09:22:04 +01:00
Christopher Dryden bca0aa08f7 Adding test to cover no dereference when copying symlinks 2025-12-10 04:17:17 +00:00
Vikram Kangotra 15d22c285e cp: allow directory merging when destination was just created (#9325)
* cp: allow directory merging when destination was just created

Previously, when copying to a destination that was created in the same
cp call, the operation would fail with "will not overwrite just-created"
for both files and directories. This change allows directories to be
merged (matching GNU cp behavior) while still preventing file
overwrites.

The fix checks if both the source and destination are directories
before allowing the merge. If either is a file, the original error
behavior is preserved to prevent accidental file overwrites.

Fixes the case where copying multiple directories to the same
destination path would incorrectly error instead of merging their
contents.

fixes: #9318

* test_cp: Update with the suggestion

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>

---------

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
2025-11-19 16:53:23 +01:00
Sylvestre Ledru 2a8a7b36e3 silent some tests for openbsd for now 2025-11-09 00:12:39 +01:00
Christopher Armstrong 37d00ae89b cp: display symlink creation with --verbose
cp: display removed files with --verbose
2025-10-15 22:30:27 +01:00
Guillem L. Jara 3a77bf40b8 chore: huge clippy pass ahead of 1.92.0 release 2025-10-13 18:06:35 +02:00
Christopher Ada Armstrong 7e12383fcf cp: show relative path of source file with -vr (#8887)
* cp: show relative path of source file with -vr

Add test to cover fix.

* fix test expected output for windows
2025-10-11 17:30:19 +02:00
Guillem L. Jara 9b1f458204 chore: add test coverage for latest cp bug fix 2025-10-10 09:43:32 +02:00
Alen Antony 52c71dcac9 Merge pull request #8747 from Anonymous-AAA/fix-recursive-cp-backslash
cp: fix recursive cp fails on files with trailing backslashes
2025-09-28 19:20:10 +02:00
Vesal J 671345fb5b cp: enhance tests for current directory attribute preservation
This commit adds tests to verify that file permissions and timestamps are preserved when copying the current directory (.) to a destination. Specific permissions and timestamps are set on the source files, and assertions are made to ensure that these attributes are correctly maintained in the copied files. The tests are conditionally compiled for non-Windows and non-FreeBSD systems.
2025-09-08 20:53:46 +03:30
Vesal J f8923d8b15 cp: fix cargo formatting 2025-09-07 19:16:22 +03:30
Vesal J e41f2118c6 cp: add tests for copying current directory (.) to various destinations
This commit introduces several tests to validate the behavior of copying the current directory (.) to both existing and new directories, including checks for verbose output, attribute preservation, and handling of symlinks. Additionally, a test is added to ensure that copying the current directory to itself is disallowed with an appropriate error message. These tests enhance coverage and ensure compliance with expected functionality.
2025-09-07 03:08:40 +03:30
Anonymous-AAA bfbdf10d3f cp: fix recursive socket file copy 2025-08-13 08:25:34 +05:30
Nicolas Boichat f8a864b15d test_cp: On MacOS, ignore tests that use /dev/fd/0
For unclear reason, this is a source of test flakiness (#8453).
2025-08-09 14:20:22 +08:00
Sylvestre Ledru 302f08266a cp: fix directory permission preservation for sibling directories with -a (Closes: #8407) 2025-08-07 22:50:50 +02:00
Martin Kunkel 3b4b769976 tests: fix execution on WSL2, Ubuntu 24.04 (#8235)
* tests: fix execution on WSL2, Ubuntu 24.04

Skip incompatible parts of tests to ensure that
    cargo nextest run --features unix
executes successfully in WSL2, Ubuntu 24.04 distribution.

Changes
* Skip tests that required sys/kernel/profiling which is not
available in WSL2 default configuration.
* Use timezones in tests that are part of the standard tzdata
list and not only available in backwards list. Backwards list is
not installed by default in Ubuntu 24.04 (package tzdata-legacy).
* check that /proc/modules is not empty when expecting content,
because it is empty in WSL2 default configuration.
* Skip logname test not only in WSL1, also in WSL2.

* Add workflow for WSL2

This will setup WSL2 on windows-latest runner, install
Ubuntu-24.04, and run the feat_os_unix tests.

* wsl2: implemented review findings

---------

Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
2025-08-03 14:38:49 +02:00
Daniel Hofstetter 9938db39bc Merge pull request #8333 from sylvestre/selinux-mv
mv: add support for selinux and add minor refactor
2025-08-01 09:36:06 +02:00
Sylvestre Ledru 6e930966fb selinux: introduce get_getfattr_output to verify the output of getfatt 2025-07-31 17:45:34 +02:00
Nicolas Boichat f4bf8987cd tests/by-util/test_cp.rs: Merge #[cfg]
Co-authored-by: Dorian Péron <72708393+RenjiSann@users.noreply.github.com>
2025-07-30 21:04:03 +08:00
Nicolas Boichat 4b11692db3 cp: Also copy attributes in copy_symlink
Most attributes can actually be applied to symlinks (mode and
xattr are exceptions), so try to copy them, if possible.

Fort those 2 exceptions, we don't need any special handling as:
 - Mode errors would be ignored anyway.
 - The source symlink cannot have any xattr anyway, so no
   attribute is attempted to be set on the destination.
2025-07-30 20:03:22 +08:00
Nicolas Boichat 4d48626eeb cp: File logic error when preserving attributes for fifos
There was a mismatch between the test, the comment, and the code.

The intention was to _preserve_ attributes if the source of a
fifo/pipe still exists. Perhaps the clearest way is to modify
the test (as that avoids code duplication).

Also add a basic test for that, if permissions are preserved, the
rest should also be preserved correctly.

Fixes the first part of #8402.
2025-07-30 17:37:51 +08:00
Nicolas Boichat 7e6e9c291e uutests: Change dir_exists to take a templated AsRef<Path>
Similar to what file_exists does, allows us to pass an OsStr to the
function.

Also change symlink_exists, for consistency.
2025-07-22 17:25:59 +08:00
Julian Andres Klode b585e98dac cp: Fix --no-dereference --parents with symlink source
If the source is a symbolic link pointing at a directory,
--parents was ignored, as we entered the "copy as directory"
code path.

Fixes: #8330
2025-07-11 08:09:10 +02:00
Yuri Astrakhan 206281e29b chore: fix uninlined_format_args lint
I used this command, plus some manual fixes:

```sh
__CARGO_FIX_YOLO=1 cargo clippy --fix --all-targets --workspace --all-features --allow-dirty
```
2025-07-09 10:50:36 +02:00
Luv-Ray 69bc6a791e cp: clean existing file when copy from stream (#8149)
* cp: clean existing file when copy from stream

* cp: remove outdated comments

---------

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
2025-07-06 16:07:22 +02:00
Daniel Hofstetter 546e50846e cp: rewrite test to remove procfs dependency 2025-06-02 09:51:33 +02:00
Daniel Hofstetter 8674e86703 cp: fix warnings from unnecessary_debug_formatting
Co-authored-by: Jeremy Smart <jeremy3141592@gmail.com>
2025-05-19 09:54:37 +02:00
Sylvestre Ledru 832dd495bf selinux: adjust more error messages 2025-05-07 22:58:46 +02:00
Sylvestre Ledru 5148ba12d6 set_selinux_security_context: also display the error from the crate
+ fix comments from review
2025-05-06 08:52:27 +02:00
Sylvestre Ledru b3a2b74ca1 cp/selinx: improve the support of --preserve-context and simplify the code.
+ Add test for the selinux changes with context SLASHLogin
Improves the coverage of tests/cp/cp-a-selinux.sh
2025-05-06 08:52:27 +02:00