The umask, is one of those UNIX fundamentals that can feel mysterious. Most of us eventually wind up with a vague notion of how it influences the permissions of new files and directories, but how exactly does it work?

The umask command is used to inspect and set the file mode creation mask, generally referred to as "the umask", of the current process. The umask, in turn, "masks out" certain bits in the mode of newly created filesystem nodes, like files and directories.

It's easier to understand how the umask is applied if you use octal digits, like 0640, as versus symbolic notation, like u=rw,g=r,o=. Sometimes you'll see modes with three digits instead of four, in which case a leading 0 is assumed. 0640, 640, and u=rw,g=r,o= are equivalent.

Each of a mode's four octal digits requires three bits to encode the range of eight possible values, 0-7 (23 = 8).  A mode is really four, three-bit, bitmasks. The left-most bitmask specifies advanced filesystem attributes.  The remaining three bitmasks specify permissions for the user owner, group owner, and everyone else.  Each bitmask records the read, write, and execute permission, from left to right.

A mode of 0640 specifies read and write for the user owner, read for members of the group owner group, and no access for everyone else.

           rwx rwx rwx
0640 = 000 110 100 000

So how exactly does it work?

The mode of a newly created filesystem node is the bitwise and of the complement (negation) of the umask and the mode specified by the program creating the new resource, typically 0666 for files and 0777 for directories.

Let's take that apart, looking at two common scenarios.

A umask of 0022 and a New File

We'll use touch(1) to create a new file and strace(1) to see the mode specified in  the  open(2) system call.

jereme@buttercup $ umask
022

jereme@buttercup $ strace -e open touch foo 2>&1 | grep -v O_CLOEXEC
open("foo", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
+++ exited with 0 +++

jereme@buttercup stat -c '%n %a/%A' foo
foo 644/-rw-r--r--

touch(1) passes a mode of 0666 to open(2).  Combined with our umask of 0022, this yields a mode of 0644 for the newly created file, foo.

First we compute the complement of our umask, 0022, by negating each bit, resulting in 7755.

           rwx rwx rwx
0022 = 000 000 010 010  # our umask
       ---------------
7755 = 111 111 101 101  # its complement

Then we compute the final mode by performing a bitwise and of the previously generated complement and the requested mode, 0666, ending up with our final mode: 0644.

           rwx rwx rwx
7755 = 111 111 101 101  # the complement of our umask
0666 = 000 110 110 110  # the mode specified by touch(1) to open(2)
       ---------------  # bitwise AND
0644 = 000 110 100 100  # the resulting mode

A umask of 0002 and a New Directory

This time tracing mkdir(1) and the mkdir(2) sys call.

jereme@buttercup $ umask
002

jereme@buttercup $ strace -e mkdir mkdir bar
mkdir("bar", 0777)                      = 0
+++ exited with 0 +++

jereme@buttercup stat -c '%n %a/%A' bar
bar 775/drwxrwxr-x
           rwx rwx rwx
0002 = 000 000 000 010  # our umask
7775 = 111 111 111 101  # the complement of our umask
0777 = 000 111 111 111  # the mode specified by mkdir(1) to mkdir(2)
       ---------------  # bitwise AND
0775 = 000 111 111 101  # the resulting mode

Where is the man page?

umask is implemented as one of the shell's built-in commands and is not a stand-alone program but rather a feature of the shell itself, like cd. You can check the "builtins" section of the man page for your shell, though some distros move or duplicate that text to its own reference.

On Debian hosts you can refer to bash(1) or bash-builtins(7), or zshbuiltins(1) for details. And while you're there, have a look at the system call umask(2).

Cover photo by Pamela Saunders