# Unfortunately, creating files and then changing their permissions # is a race condition: some other user could come at the wrong # moment, and open the file while it had incorrect permissions # (between creation and ‹chmod›). In most cases, it is not a huge # risk, but it is a risk and in certain circumstances can lead to # serious security problems. # There are multiple mechanisms that can be used to close this # loophole, one of them being ‹umask›. The other is specifying the # permissions at the time the file is being created, but this is # mainly an option for C programs. On the user side of things, not # many tools allow the user to specify the permissions they want for # a particular new file. # This is where ‹umask› comes in: the operating system maintains a # per-process «permission mask» (called ‹umask›) which is subtracted # from permissions of each newly created file. Most shells allow the # user to manipulate this mask, and all programs executed by the # shell inherit the mask from the shell (since it is inherited # across ‹fork›). # When a file is created, all the bits that are set in the ‹umask› # are cleared: echo umask 777 umask 777 touch umask.txt ls -l umask.txt rm -f umask.txt # The clearing of permission bits from ‹umask› happens atomically: a # file with the permission bits set does not exist, not even # temporarily. Of course, 777 makes little sense as an actual # ‹umask›, but it does demonstrate what is going on. A more # reasonable (though also somewhat paranoid) option would be 077, # which means new files are only accessible to the owner (i.e. the # creator of the file, i.e. us): echo echo umask 077 umask 077 touch umask.txt ls -l umask.txt rm -f umask.txt # Let's try to create a file that is marked executable by the tool # that creates it. A compiler is a good example: echo echo umask 077 with cc echo 'int main() {}' > empty.c cc empty.c ls -l a.out rm -f a.out # A somewhat less reasonable ‹umask› (again only useful for # demonstration purposes) would deny any executable bits: echo echo umask 133 with cc umask 133 cc empty.c ls -l a.out rm -f a.out # And finally, a fairly common default would be 022: this prevents # anyone but the owner from writing into new files, but anyone else # can read and/or execute them if they wish so. echo echo umask 022 umask 022 touch file.txt cc empty.c ls -l a.out file.txt rm -f a.out file.txt # Possibly useful: if you run ‹umask› without arguments, it will # print the currently active ‹umask›. That said, let's look at # creating files in C now, and specifically setting their # permissions upon creation. See ‹perm.c›.