The umask value is subtracted from the full permission set for an object.
This isn't true. Or at least it's inaccurate and simplified to a common case.
First, the base value is not "the full set of permissions", but instead whatever the process creating the file sets as the file permissions. Granted, for regular files, this is usually
0666: the idea being that (say) a text editor shouldn't decide what the permissions of a file should be, but the user should be allowed to decide it via the
But a process creating the file doesn't need to use
0666 as the file permissions. For private files (think SSH keys),
0600 would be used, so that regardless of the umask, the file is never accessible by others than the owner.
Also, for executable files,
0777 could be used so that the resulting file is executable.
0777 would be common, since the
x bit is practically as necessary as the
r bit for general use. For general data files, it isn't, so this is why the common case is
0666 for files, and
0777 for directories.
The base permissions used could of course be something else, but those are likely to be the common cases.
Second, the value of the umask is not subtracted, but masked out. Subtraction implies a carry from one bit to the next up, and subtracting e.g. the
0666 would result in
0657. That's not how the umask works, and that would not be useful.
Note that the umask is only used when a file is created, the Linux man page also calls it the "file mode creation mask". After that,
chmod() can be used to change the permissions without being limited by the umask.
So if a file can't be have read, write, execute permissions at once,
Sure, they can. It's just not useful for nonexecutable files.