walker walker - 10 months ago 42
C Question

Why can't my program set 0777 mode with the mkdir system call?

I wrote following code to try to create a directory with 0777 mode on Linux:

#include <sys/stat.h>
#include <sys/types.h>

int main () {

mkdir("/tmp/mkdir-test", 0777);
return 0;


But actually, the new directory has 0755 mode.

# stat /tmp/mkdir-test
File: `/tmp/mkdir-test'
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 802h/2050d Inode: 1772304 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2016-09-27 20:23:54.000000000 -0700
Modify: 2016-09-27 20:23:54.000000000 -0700
Change: 2016-09-27 20:23:54.000000000 -0700

Can someone explain this? And how can the program create a real 0777 mode directory?

Answer Source

Run umask in the shell; it will report 022. The bits set in the umask value are removed from permissions when creating files or directories.

To really set 0777 permissions, you'll need to dink with umask():

mode_t old_mask = umask(0);
mkdir("/tmp/mkdir-test", 0777);

That preserves the current setting except when you are sure you need to override it.

Incidentally, the other option for setting the permissions is:

const char *dirname = "/tmp/mkdir-test";
if (mkdir(dirname, 0777) == 0)
    chmod(dirname, 0777);

The chmod() function is not affected by umask values. The permissions on the call to mkdir() are not critical; you could use 0 if you wanted to. This method is less satisfactory if you're trying to restrict the permissions rather than relax them as in your case — there's a TOCTOU (Time-of-Check, Time-of-Use) style vulnerability between the mkdir() and chmod() calls during which someone could get into a directory with relaxed permissions and this could be a security risk. It's better to use the umask() method. umask() is a very simple system call and therefore very quick too (as system calls go, compared with heavyweights such as open() or mkdir()).