Skip to content

Conversation

@abendrothj
Copy link
Contributor

@abendrothj abendrothj commented Dec 23, 2025

feat: enable safe traversal on all Unix platforms

Expands the safe_traversal module support from target_os = "linux" to unix, enabling security improvements (specifically preventing TOCTOU races) on macOS and BSDs.

Changes:

  • Feature Guards: Replaced #[cfg(target_os = "linux")] with #[cfg(unix)] in uucore, du, chmod, and rm.
  • Refactoring: Renamed src/uu/rm/src/platform/linux.rs to unix.rs to reflect the broader platform support.
  • Type Safety: Added necessary type casts in safe_traversal.rs and du.rs to handle platform-specific differences in libc types (e.g., mode_t).

Verification:
Verified with cargo test on macOS.

Closes #9747

@github-actions
Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/misc/tee (passes in this run but fails in the 'main' branch)

Copy link
Contributor

@sylvestre sylvestre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plenty of jobs are failing, please fix them

- Use 'as u64' casts with clippy::unnecessary_cast suppression for
  st_nlink and st_ino to handle platform-specific type differences
- Add TOCTOU (time-of-check time-of-use) to cspell dictionary

Fixes compilation errors on FreeBSD, OpenBSD, and Android where
libc types differ from Linux/macOS (st_nlink is u16, st_ino is u32).
The cast is unnecessary on some platforms but required on others,
hence the clippy suppression.
Resolved merge conflict in src/uu/du/src/du.rs by keeping the unix
cfg guard (not target_os = "linux") to align with the PR's goal of
expanding safe_traversal to all Unix platforms.
@abendrothj abendrothj requested a review from sylvestre December 27, 2025 15:11
@sylvestre
Copy link
Contributor

Still a few job failures

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/cp/cp-mv-enotsup-xattr. tests/cp/cp-mv-enotsup-xattr is passing on 'main'. Maybe you have to rebase?
Note: The gnu test tests/csplit/csplit-io-err was skipped on 'main' but is now failing.

abendrothj and others added 3 commits December 28, 2025 01:10
This commit addresses compilation errors and test failures on macOS and BSD
platforms introduced by the safe_traversal expansion to Unix platforms.

**SELinux Platform Guards (8 files):**
The SELinux module in uucore is Linux-only, gated behind
`#[cfg(all(target_os = "linux", feature = "selinux"))]`. However, code
was only checking `#[cfg(feature = "selinux")]`, causing compilation
failures on macOS/BSDs where uucore::selinux doesn't exist.

Fixed by updating all SELinux feature checks from:
  `#[cfg(feature = "selinux")]`
to:
  `#[cfg(all(feature = "selinux", target_os = "linux"))]`

Modified files:
- src/uu/cp/src/cp.rs (2 locations)
- src/uu/id/src/id.rs (4 locations)
- src/uu/install/src/install.rs (17 locations)
- src/uu/mkdir/src/mkdir.rs (1 location)
- src/uu/mkfifo/src/mkfifo.rs (1 location)
- src/uu/mknod/src/mknod.rs (1 location)
- src/uu/stat/src/stat.rs (2 locations)

**Type Conversion Fix:**
On macOS, `libc::mode_t` is `u16` while `metadata.permissions().mode()`
returns `u32`, causing a type mismatch in rm's safe_traversal code.

Fixed in src/uu/rm/src/platform/unix.rs:320 by adding explicit cast:
  `initial_mode as libc::mode_t`

**Test Fix:**
Updated test_chmod_recursive to expect consistent error messages across
all Unix platforms. With safe_traversal now enabled universally on Unix,
the detailed error format "cannot access 'z': Permission denied" is used
on all platforms, not just Linux.

Modified: tests/by-util/test_chmod.rs

**Verification:**
- ✅ All unit tests pass (chmod, du, rm, cp, id, stat, mkdir, mkfifo, mknod, install, uucore)
- ✅ All functional tests pass
- ✅ cargo build --features feat_os_macos
- ✅ cargo build --features feat_os_unix
- ✅ cargo clippy (macOS & Unix features)
- ✅ cargo fmt --all -- --check
- ✅ chmod integration tests (40/40 passed)
@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/sort/sort-stale-thread-mem. tests/sort/sort-stale-thread-mem is passing on 'main'. Maybe you have to rebase?

Fixes multiple platform-specific type issues in safe_traversal.rs:

1. **Clippy unnecessary_cast warnings** - Add #[allow(clippy::unnecessary_cast)]
   to dev(), mode(), and rdev() methods. These casts are unnecessary on Linux
   where types are already u64/u32, but required on macOS/BSD where:
   - st_dev is i32 (needs cast to u64)
   - st_mode is u16 (needs cast to u32)
   - st_rdev is i32 (needs cast to u64)

2. **Android type mismatch** - Cast st_mode to libc::mode_t in file_type()
   method. On Android, st_mode is u32 but libc::mode_t is u16, causing
   compilation failure when passing to FileType::from_mode().

These fixes match the existing pattern already used for st_ino and st_nlink.

Resolves:
- Style/lint (ubuntu-latest, all, true) - clippy errors
- Style and Lint (unix) - OpenBSD clippy errors
- Test builds (Android x86/x86_64) - type mismatch errors
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail/assert is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail/assert is no longer failing!

abendrothj and others added 3 commits December 28, 2025 04:39
…modules & disable safe dir for Redox (assumedly will be handled in another PR but can implement Redox specific version if requested)
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail/assert is no longer failing!

- Fix type mismatches in rm's unix.rs by casting libc constants to u16 to match st_mode
- Add Redox stubs for safe_traversal to prevent build errors on Redox
- Make locale format tests robust: only enforce strict checks on platforms with locale support (Linux, macOS, BSDs)

These changes ensure safe directory traversal and related utilities build and test cleanly across all Unix targets, including Redox, and CI passes regardless of locale support.
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail/assert is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tail/assert is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/timeout/timeout (passes in this run but fails in the 'main' branch)

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/shuf/shuf-reservoir. tests/shuf/shuf-reservoir is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/sort/sort-stale-thread-mem. tests/sort/sort-stale-thread-mem is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/tail/overlay-headers (fails in this run but passes in the 'main' branch)

Make safe-traversal feature conditional for chmod and du crates,
enabling compilation on Redox OS which lacks support for the
fstatat syscalls required by uucore's safe_traversal module.

Changes:
- Move safe-traversal to platform-specific dependencies for non-Redox Unix
- Add guards to exclude DirFd usage on Redox
- Provide Redox-specific implementation for chmod's walk_dir_with_context
  using standard filesystem operations
- Add guard to du's new_from_dirfd to match its DirFd import guard

Both utilities now fall back to standard fs operations on Redox.
@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tty/tty-eof is no longer failing!

@github-actions
Copy link

GNU testsuite comparison:

Congrats! The gnu test tests/tty/tty-eof is no longer failing!

@abendrothj
Copy link
Contributor Author

abendrothj commented Dec 31, 2025

That should do it. Let me know if there's anything else needed for this pr to be merged

@sylvestre
Copy link
Contributor

@sylvestre That should do it. Let me know if there's anything else needed for this pr to be merged

still a bunch of jobs are failing :)

@abendrothj
Copy link
Contributor Author

Oh wow, was passing completely until I updated the branch. Will fix

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

GNU testsuite comparison:

Congrats! The gnu test tests/basenc/bounded-memory is now passing!
Note: The gnu test tests/dd/no-allocate was skipped on 'main' but is now failing.

@abendrothj
Copy link
Contributor Author

abendrothj commented Jan 5, 2026

A new test was added in that merge (added in commit abd581f) and was failing since it was expecting the old linux-only safe traversal setup. Should be adjusted to the unixification now @sylvestre :)

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

GNU testsuite comparison:

Congrats! The gnu test tests/basenc/bounded-memory is now passing!
Note: The gnu test tests/dd/no-allocate was skipped on 'main' but is now failing.

@abendrothj
Copy link
Contributor Author

Should be cleaner now!

@abendrothj abendrothj requested a review from sylvestre January 7, 2026 12:41
; resolve SMACK conflicts
@github-actions
Copy link

github-actions bot commented Jan 9, 2026

GNU testsuite comparison:

Skipping an intermittent issue tests/tty/tty-eof (passes in this run but fails in the 'main' branch)

@sylvestre sylvestre merged commit 30239e6 into uutils:main Jan 9, 2026
131 of 132 checks passed
@sylvestre
Copy link
Contributor

well done

@abendrothj
Copy link
Contributor Author

Thanks! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Safe traversal module only enabled on Linux

2 participants