umask is subtractive, not prescriptive: permission bits set in umask are removed by default from modes specified by programs, but umask can't add permission bits.
touch specifies mode 666 by default (the link is to the GNU implementation, but others behave in the same way; this is specified by POSIX), so the resulting file ends up with that masked by the current
umask: in your case, since
umask doesn't mask anything, the result is 666.
The mode of a file or directory is usually specified by the program which creates it; most system calls involved take a mode (e.g.
mkdir(2) all have a mode parameter; but
fopen(2) doesn't, and uses mode 666). Unless the parent directory specifies a default ACL, the process's umask at the time of the call is used to mask the specified mode (bitwise
mode & ~umask; effectively this subtracts each set of permissions in umask from the mode), so the umask can only reduce a mode, it can't increase it. If the parent directory specifies a default ACL, that's used instead of the umask: the resulting file permissions are the intersection of the mode specified by the creating program, and that specified by the default ACL.
POSIX specifies that the default mode should be 666 for files, 777 for directories; but this is just a documentation default (i.e., when reading POSIX, if a program or function doesn't specify a file or directory's mode, the default applies), and it's not enforced by the system. Generally speaking this means that POSIX-compliant tools specify mode 666 when creating a file, and mode 777 when creating a directory, and the umask is subtracted from that; but the system can't enforce this, because there are many legitimate reasons to use other modes and/or ignore umask:
- compilers creating an executable try to produce a file with the executable bits set (they do apply umask though);
chmod(1) obviously specifies the mode depending on its parameters, and it ignores umask when "who" is specified, or the mode is fully specified (so
chmod o+x ignores umask, as does
chmod 777, but
chmod +w applies umask);
- tools which preserve permissions apply the appropriate mode and ignore umask: e.g.
- tools which take a parameter fully specifying the mode also ignore umask:
So you should think of umask as specifying the permission bits you don't want to see set by default, but be aware that this is just a request. You can't use it to specify permission bits you want to see set, only those you want to see unset. Furthermore, any process can change its umask anyway, using the
umask(2) system call! The
umask(2) system call is also the only POSIX-defined way for a process to find out its current umask (inherited from its parent). On Linux, starting with kernel 4.7, you can see a process's current umask by looking for
(For the sake of completeness, I'll mention that the behaviour regarding
setgid and sticky bits is system-dependent, and remote filesystems such as NFS can add their own twists.)