Commit Graph
114 Commits
Author SHA1 Message Date
Etienne CordonnierandDaniel Hofstetter 76c63ee6fd install: update comments and tests
Fix doc comments in safe_traversal that still described the old behavior
of replacing symlinks with real directories. Rename and deduplicate tests
that were originally written as race-condition regression tests but now
just verify symlink-following behavior.

Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com>
2026-05-26 10:14:21 +02:00
Jake AbendrothandGitHub 21fda8cd9f fix(install): follow symlink components in destination path with -D
## Summary

Fixes #11469

`install -D` was replacing pre-existing symlinks in the destination path with real directories instead of following them. This broke any workflow where part of the install prefix is a symlink; including BOSH deployments, Homebrew, Nix, stow, and any `make install` targeting a symlinked prefix.

**Reproduction (from the issue):**
```sh
mkdir -p /tmp/target
ln -s /tmp/target /tmp/link
echo hello > /tmp/file.txt
install -D -m 644 /tmp/file.txt /tmp/link/subdir/file.txt
# GNU coreutils 8.32: /tmp/link stays a symlink, file lands in /tmp/target/subdir/file.txt
# uutils 0.7.0:       /tmp/link is replaced with a real directory — wrong
```

## Root cause

PR #10140 introduced `create_dir_all_safe()` in `safe_traversal.rs` to prevent TOCTOU symlink race conditions. The fix was correct in intent but too aggressive: `open_or_create_subdir()` unconditionally unlinked and recreated any symlink it encountered, including pre-existing legitimate ones.

## Changes

**`src/uucore/src/lib/features/safe_traversal.rs`**
- `open_or_create_subdir`: when `stat_at` returns `S_IFLNK`, call `open_subdir(Follow)` instead of `unlink_at + mkdir_at`. The `O_DIRECTORY` flag already in `open_subdir` means dangling or non-directory symlinks still return an error cleanly.
- `find_existing_ancestor`: switch from `fs::symlink_metadata` to `fs::metadata` so that a symlink-to-directory is recognised as an existing ancestor rather than a component to recreate (this was already the stated intent in the function's doc comment).

**`src/uu/install/src/install.rs`**
- Align the `dir_exists` check and the `DirFd::open` call to also follow symlinks, consistent with the above.

**`tests/by-util/test_install.rs`**
- Update the two tests added by #10140 — they were asserting the buggy behavior (symlink replaced). Flip the assertions to document the correct GNU behavior.
- Add `test_install_d_follows_symlink_prefix` as a direct regression test for the issue's reproduction case.

## TOCTOU / security note

The true TOCTOU race (a symlink *injected during the operation* into a not-yet-existing path component) is still blocked: `mkdirat` fails with `EEXIST` if an attacker creates a symlink between `stat_at` returning `ENOENT` and our `mkdir_at`. Newly-created directories are still opened with `O_NOFOLLOW`.

What changes is that *pre-existing* symlinks are now followed — which is exactly what GNU coreutils 8.32 does. The previous behavior was stricter than GNU in this regard.
2026-05-25 22:11:50 +02:00
xtqqczzeandDaniel Hofstetter 7449705a98 fix(tests): refine feature checks for SELinux 2026-05-19 11:19:55 +02:00
Sylvestre LedruandDaniel Hofstetter f057cc6a01 tests: replace .no_stdout().no_stderr() chains with .no_output()
Bulk rename of the antipattern across 19 test files (136 occurrences).
.no_output() is the established shorthand in the uutests framework
for asserting both empty stdout and empty stderr.
2026-05-12 09:31:31 +02:00
oech3andDaniel Hofstetter 94f9224ce2 Disable strip related tests on Android 2026-02-21 16:59:08 +01:00
Jake AbendrothandGitHub 0c41299975 fix(install): prevent symlink race condition in install -D (fixes #10013) (#10140) 2026-02-14 21:47:33 +01:00
✿ Fleur de BlueandGitHub 2a2cafdbd4 Re-enable unused_qualifications lint (#10571) 2026-02-03 21:55:21 +01:00
Dalton CaronandGitHub b5bbabc18a install: prevent TOCTOU race attack (#10067)
* install: prevent TOCTOU race attack

* cspell: add TOCTOU acronym to jargon word list
2026-01-17 18:08:14 +01:00
Sylvestre LedruandGitHub 8c10759e2c Merge pull request #9526 from alexandrefresnais/feature/install_unprivileged
install: add FreeBSD's -U (unprivileged) option
2025-12-29 14:44:21 +01:00
RustyJackandGitHub 939ab037a2 uucore: use --suffix to enable backup mode (#9741) 2025-12-21 10:17:35 +01:00
Alexandre Fresnais 8c7434cf36 install: add -U (unprivileged) option 2025-12-20 19:19:25 +01:00
747874911a Enhance mode parsing to support comma-separated mode strings in install command (#9298)
* Enhance mode parsing to support comma-separated mode strings in `parse` function. Add tests for comma-separated mode handling in file and directory creation.

* Add comprehensive tests for mode parsing in `parse` function, covering numeric, symbolic, and mixed modes, as well as handling of invalid inputs and umask considerations.

---------

Co-authored-by: Sylvestre Ledru <sylvestre@debian.org>
2025-11-17 10:14:22 +01:00
Adrian Kretz 4d71a6e2d2 test/install: add test to ignore umask 2025-11-13 00:30:30 +01:00
Sylvestre Ledru 30dbdf7ac7 install: fix the error message
should fix: tests/install/basic-1.sh
2025-11-08 10:58:46 +01:00
Sylvestre Ledru 2434c2ae13 Install: implement -Z
Fixes: tests/install/install-Z-selinux
2025-10-21 23:27:06 +02:00
Sylvestre Ledru 83e5be8a52 install: options support non-ut8 too 2025-08-14 10:54:17 +02:00
Sylvestre Ledru 39b7721464 Fix install to handle non-UTF-8 filenames 2025-08-14 10:52:24 +02:00
Daniel Hofstetter d9af611a9f install: disable two tests on macOS x86_64
they run in timeouts in the CI with macos-latest
2025-08-02 17:33:41 +02:00
Sylvestre Ledru 6e930966fb selinux: introduce get_getfattr_output to verify the output of getfatt 2025-07-31 17:45:34 +02:00
Julian Andres Klode 190ddd105c install: Fix --no-target-directory with existing file
install should silently override existing target files, but it
inadvertently checked whether the target exists rather than
for the target being a directory, hence the overwrite failed,
saying it cannot overwrite the directory with non-directory.

Bug-Ubuntu: https://bugs.launchpad.net/bugs/2118785
2025-07-29 12:24:31 +02:00
Julian Andres Klode abb5300068 install, mkdir: Handle dir/./ like dir/.
The dir/. special case was handled correctly, but dir/./ was not,
breaking gcc builds, which run:

../../../../src/libstdc++-v3/../install-sh -c -d debug/./

Bug-Ubuntu: https://bugs.launchpad.net/bugs/2117466
2025-07-22 09:44:15 +02:00
Yuri AstrakhanandDaniel Hofstetter 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
Sylvestre Ledru d9c72dcdc8 install -C: also the manage the ignore case 2025-06-29 23:51:45 +02:00
bdcd2ef00a install: implement option -C
Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
2025-06-29 23:19:09 +02:00
jenningsfanandGitHub 3214c4d604 install: don't error when multiple arguments of the same type are given, instead override with last one (#8033) (#8053) 2025-06-28 09:57:55 +02:00