Skip to content

Conversation

@rynewang
Copy link
Contributor

@rynewang rynewang commented Jan 3, 2026

Fix #10022: mkdir -m MODE was creating directories with umask-based permissions first, then calling chmod afterward. This left a brief window where the directory existed with wrong permissions.

Now we match GNU mkdir behavior by temporarily setting umask to 0 before the mkdir syscall, passing the exact requested mode to the kernel, then restoring the original umask. The directory is created atomically with the correct permissions.

Before (two syscalls, race condition):
mkdir("dir", 0777) -> created with 0755 (umask applied)
chmod("dir", 0700) -> fixed afterward

After (single syscall, atomic):
umask(0)
mkdir("dir", 0700) -> created with exact mode
umask(original)

Also added tests to verify -m MODE bypasses umask correctly.

Fix uutils#10022: mkdir -m MODE was creating directories with umask-based
permissions first, then calling chmod afterward. This left a brief
window where the directory existed with wrong permissions.

Now we match GNU mkdir behavior by temporarily setting umask to 0
before the mkdir syscall, passing the exact requested mode to the
kernel, then restoring the original umask. The directory is created
atomically with the correct permissions.

Before (two syscalls, race condition):
  mkdir("dir", 0777)  -> created with 0755 (umask applied)
  chmod("dir", 0700)  -> fixed afterward

After (single syscall, atomic):
  umask(0)
  mkdir("dir", 0700)  -> created with exact mode
  umask(original)

Also added tests to verify -m MODE bypasses umask correctly.
@alippai
Copy link

alippai commented Jan 3, 2026

Is coreutils supposed to be used as a multithreaded lib? Umask changes the whole process, all threads. If safety is needed adding Drop + mutex can make it more robust

@github-actions
Copy link

github-actions bot commented Jan 3, 2026

GNU testsuite comparison:

Congrats! The gnu test tests/tail/follow-name is no longer failing!

@sylvestre
Copy link
Contributor

Is coreutils supposed to be used as a multithreaded lib? Umask changes the whole process, all threads. If safety is needed adding Drop + mutex can make it more robust

Yes and no. We focus on the cli first but we have some users like nushell.

@rynewang
Copy link
Contributor Author

rynewang commented Jan 3, 2026

I can add mutex and Drop but I wonder how much it can help. If a downstream user users uutils/coreutils as a library then their own umask or fork calls can't be protected by any of our mutexes.

@rynewang
Copy link
Contributor Author

rynewang commented Jan 3, 2026

One approach is to fork a subprocess that does umask, mkdir and exit. But I wonder if this is an overkill and a mutex + drop guard is enough?

@rynewang
Copy link
Contributor Author

rynewang commented Jan 4, 2026

@sylvestre can you provide some directions on whether I should go with:

  1. a drop guard, or
  2. fork a subprocess to umask and mkdir and exit ?

@sylvestre
Copy link
Contributor

for now, just focus on the binary itself, we will see for the lib later

Add RAII guard to ensure umask is restored even on panic. Encapsulate
unsafe umask calls in UmaskGuard::set() for a safe interface.
@rynewang
Copy link
Contributor Author

rynewang commented Jan 4, 2026

updated with the drop guard

- Add RAII to spell-checker ignore list
- Narrow chmod cfg to Linux only (only used for ACL bits)
@github-actions
Copy link

github-actions bot commented Jan 4, 2026

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?
Skip an intermittent issue tests/timeout/timeout (fails in this run but passes in the 'main' branch)

@sylvestre
Copy link
Contributor

some jobs are failing

FromIo is only used in chmod, which is now Linux-only.
@github-actions
Copy link

github-actions bot commented Jan 4, 2026

GNU testsuite comparison:

Skip an intermittent issue tests/timeout/timeout (fails in this run but passes in the 'main' branch)
Note: The gnu test tests/csplit/csplit-heap is now being skipped but was previously passing.

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.

mkdir -m creates directory with wrong permissions, briefly

3 participants