Hi, I just ran into some inconsistencies wrt permissions and `os.Mkdir()`, at least on Linux. I'm not sure what part of this is actual bugs that need to be fixed and what is a documentation bug, but let me state what I've found.
The documentation for Mkdir says: "Mkdir creates a new directory with the specified name and permission bits.". To me, this suggests that any permissions would be applied as-is, with no further processing. However, in practice, on at least Linux and probably other unices, the umask is applied: matthijs@grubby:/tmp$ cat test.go package main import "os" func main() { os.Mkdir("/tmp/foo", 0770) } matthijs@grubby:/tmp$ go build test.go matthijs@grubby:/tmp$ ./test matthijs@grubby:/tmp$ ls -ld foo drwxr-x--- 2 matthijs matthijs 4096 Dec 13 14:25 foo (Note missing g+w bit) matthijs@grubby:/tmp$ rmdir foo matthijs@grubby:/tmp$ umask 0 matthijs@grubby:/tmp$ ./test matthijs@grubby:/tmp$ ls -ld foo drwxrwx--- 2 matthijs matthijs 4096 Dec 13 14:25 foo (Note permissions are as requested) matthijs@grubby:/tmp$ umask 777 matthijs@grubby:/tmp$ rmdir foo matthijs@grubby:/tmp$ ./test matthijs@grubby:/tmp$ ls -ld foo d--------- 2 matthijs matthijs 4096 Dec 13 14:25 foo (Note all permissions masked away) By itself, this is not uncommon for mkdir, it's just calling the mkdir syscall, so it behaves the same as the libc mkdir as well. This suggests this is merely a documentation bug. However, when looking at the source for Mkdir <https://github.com/golang/go/blob/8776be153540cf450eafd847cf8efde0a01774dc/src/os/file.go#L220-L223>, I find: // mkdir(2) itself won't handle the sticky bit on *BSD and Solari if !supportsCreateWithStickyBit && perm&ModeSticky != 0 { Chmod(name, perm) } This means that, on BSD platforms (which also have umask), an explicit Chmod happens using the passed permissions, completely bypassing umask. This is at least inconsistent and surprising, and could be a security problem in some cases. I also suspect that both of these problems exist exactly like this for OpenFile (I assume OpenFile also adheres to umask without this being documented, and it also special cases for the sticky bit <https://github.com/golang/go/blob/8776be153540cf450eafd847cf8efde0a01774dc/src/os/file_unix.go#L159-L163> ). As suggested by the docs, I'm asking here before filing a bug, since I'm not sure what the exact bug and path forward should be from here. Making the permission argument behave as documented and always running a chmod seems like an obvious fix, but that completely breaks compatibility, likely resulting in security problems, so that seems out of the question... A backward compatible fix in user code would be to just pass 0 as the permission to Mkdir or OpenFile, and then manually Chmod to whatever value is needed, which should be secure and work in most cases (except when some other process is waiting for the directory or file to be created, exposing a race condition). Gr. Matthijs -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.