Skip to content

fix(install): zero umask at startup so ancestor dirs are created at exact 0755#12715

Open
abendrothj wants to merge 4 commits into
uutils:mainfrom
abendrothj:fix/install-zero-umask-ancestor-dirs
Open

fix(install): zero umask at startup so ancestor dirs are created at exact 0755#12715
abendrothj wants to merge 4 commits into
uutils:mainfrom
abendrothj:fix/install-zero-umask-ancestor-dirs

Conversation

@abendrothj

@abendrothj abendrothj commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #12714
Related: #11363, #12713

Root cause

GNU install calls umask(0) early in main() so that ancestor directories created by -D/-d always get exactly DEFAULT_MODE (0755) regardless of the caller's umask. uutils passed DEFAULT_MODE to mkdirat/fs::create_dir_all without zeroing umask first, so restrictive umasks (e.g. 0027, 0077, 0111) produced wrong ancestor modes.

The existing tests masked this because they used a mkdir-based probe to capture the expected permissions. With umask 0002 the probe yields 0775 while install produces 0755 — causing a spurious test failure that looked like a bug in the tests, not the implementation.

Changes

src/uucore/src/lib/features/mode.rs

  • Add zero_umask() using the existing rustix dependency — sets process umask to 0 and returns the old value

src/uu/install/src/install.rs

  • Call uucore::mode::zero_umask() at the top of uumain (unix only), matching GNU's behaviour
  • Fix the -d code path (directory()) to use DirBuilder::mode(DEFAULT_MODE) instead of fs::create_dir_all, which defaults to mode 0777 and would create 0777 ancestors now that the umask is zeroed

tests/by-util/test_install.rs

  • Replace the broken probe-based assertions in test_install_ancestors_mode_directories and test_install_ancestors_mode_directories_with_file with assert_eq!(0o40_755_u32, ...), which is the value GNU actually guarantees

Test plan

  • cargo test --features unix test_install — all 92 install tests pass
  • Verify manually with a non-022 umask that ancestor dirs land at exactly 0755

…xact 0755

GNU install calls umask(0) early in main() so that ancestor directories
created by -D/-d always get exactly DEFAULT_MODE (0755) regardless of the
caller's umask. Our implementation passed DEFAULT_MODE to mkdirat /
fs::create_dir_all without zeroing umask first, so restrictive umasks
(e.g. 0027, 0077, 0111) produced wrong ancestor modes.

Changes:
- Add zero_umask() to uucore::mode using the existing rustix dependency
- Call it at the top of install's uumain (unix only)
- Fix the -d code path to use DirBuilder::mode(DEFAULT_MODE) instead of
  fs::create_dir_all, which defaults to 0777 and would create 0777
  ancestors with umask now zeroed
- Replace the broken probe-based assertions in two tests with direct
  assert_eq!(0o40_755) checks, matching the GNU-guaranteed value

Fixes uutils#12714
Related: uutils#11363, uutils#12713
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/misc/io-errors (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/inotify-dir-recreate (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/expand/bounded-memory is now being skipped but was previously passing.

@abendrothj

Copy link
Copy Markdown
Contributor Author

CI is clean except for one failure: Build (ubuntu-latest, x86_64-unknown-linux-musl, feat_os_unix_musl, use-cross). This is a transient infrastructure issue, not related to the code changes — the job failed in 54 seconds with 0 compile requests recorded by sccache, meaning the cross Docker container never started. The same job passes on main in ~8 minutes. All other checks pass including the equivalent musl builds for aarch64, riscv64, and i686, the GNU test suite, BusyBox, Toybox, style, spelling, and all platform builds (Linux, macOS, Windows, WASM, Redox, NetBSD).

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.

install: ancestor directories respect process umask instead of using fixed 0755 (diverges from GNU)

1 participant