Skip to content

useradd, skel: set mkdir mode atomically to close world-writable window (#157) - #158

Merged
pierre-warnier merged 1 commit into
mainfrom
fix/157-mkdir-mode
Apr 23, 2026
Merged

useradd, skel: set mkdir mode atomically to close world-writable window (#157)#158
pierre-warnier merged 1 commit into
mainfrom
fix/157-mkdir-mode

Conversation

@pierre-warnier

Copy link
Copy Markdown
Collaborator

Summary

Fix #157. Reported by @collinfunk in uutils/coreutils#11828.

std::fs::create_dir(path) calls mkdir(path, 0o777) and the actual mode is 0o777 & ~umask. With an attacker-controlled umask (inherited across setuid since the kernel does not reset it), the directory exists with permissive bits between mkdir and the subsequent set_permissions call.

Changes

  • useradd.rscreate_home_directory now grabs UmaskGuard::zero() then uses DirBuilder::new().mode(0o700).create(...). Post-mkdir set_permissions removed.
  • skel.rs — top-level UmaskGuard::zero() for the entire copy. Subdirectories use DirBuilder::mode(src_mode).create(...). Files opened with OpenOptions::new().create_new(true).mode(src_mode).open(...) + io::copy instead of std::fs::copy (which goes through umask internally).
  • atomic.rsUmaskGuard and UmaskGuard::zero() made pub so consumers in other crates can reuse the existing RAII guard.

Test plan

  • New regression test test_integration_home_directory_ignores_inherited_umask (root-only): sets process umask to 0o000, calls create_home_directory, asserts the resulting directory mode is exactly 0o700. Passes.
  • cargo fmt --all --check — clean
  • cargo clippy --workspace --all-targets -- -D warnings — zero warnings
  • cargo test --workspace — all pass
  • Pre-push hook: full test suite on debian/alpine/fedora — all pass

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses #157 by eliminating umask-influenced permission windows during home directory and skeleton file creation, using atomic mode-setting at mkdir(2) / open(2) time plus an RAII umask guard.

Changes:

  • useradd: create home directories via DirBuilder::mode(0o700) under UmaskGuard::zero() and remove post-creation chmod.
  • shadow-core/skel: copy skeleton dirs/files using DirBuilder::mode(...) and OpenOptions::mode(...).create_new(true) under UmaskGuard::zero(), avoiding std::fs::copy.
  • shadow-core/atomic: expose UmaskGuard publicly for reuse by other crates.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/uu/useradd/src/useradd.rs Uses atomic mkdir mode + UmaskGuard for home creation; adds a regression test.
src/shadow-core/src/skel.rs Makes skeleton copy set modes at creation time (dirs/files) under UmaskGuard.
src/shadow-core/src/atomic.rs Makes UmaskGuard public and documents !Send behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/shadow-core/src/skel.rs
Comment thread src/uu/useradd/src/useradd.rs
Comment thread src/uu/useradd/src/useradd.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/uu/useradd/src/useradd.rs Outdated
Comment thread src/uu/useradd/src/useradd.rs Outdated
Comment thread src/shadow-core/src/skel.rs
Comment thread src/shadow-core/src/skel.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/uu/useradd/src/useradd.rs
Comment thread src/uu/useradd/src/useradd.rs Outdated
…ow (#157)

std::fs::create_dir(path) calls mkdir(path, 0o777) and the actual mode
is 0o777 & ~umask. With an attacker-controlled umask (inherited across
setuid since the kernel does not reset it), the directory exists with
permissive bits between mkdir and the subsequent set_permissions call.

Fix uses DirBuilder::mode(...).create(...) so the mode is set in the
syscall itself, wrapped in UmaskGuard::zero() to neutralize umask
interference. Same pattern applied to skel.rs for subdirectory and
file copies (file copies switch from fs::copy to OpenOptions::mode +
io::copy for the same reason).

Regression test asserts a process running with umask 0 still produces
a 0o700 home directory.

Reported by @collinfunk in uutils/coreutils#11828.
Fixes #157.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pierre-warnier
pierre-warnier merged commit befcac0 into main Apr 23, 2026
10 checks passed
@pierre-warnier
pierre-warnier deleted the fix/157-mkdir-mode branch April 23, 2026 07:40
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.

useradd, skel: mkdir/file creation honors umask, leaving world-writable window

2 participants