Native Linux file permissions are often denoted as “r” (read), “w” (write), and “x” (executable, which in the case of a directory means that a user can change into the directory). Treating them as binary flags with the values r = 4, w = 2, and x = 1, we can express any combination in a single digit. This scheme is repeated three times to denote independent permissions for the file owner, any user in the group of the file, and anyone else. For example, a file with permissions 0644 or rw-r--r--, is readable and writeable only by the owner (rw-). Users in the group of the file and anybody else has read-only access (r--). However, what does the leading 0 mean? There is more to it. I introduce to you: the sticky bit and its friends.

The leading zero indicates that we have yet another set of three binary flags that control the file’s permissions. Their meaning is sometimes very subtle.

What the bits mean

Let’s first check what each bit means. This depends on the type of the file objects, i.e., if it is a file or a directory. The behaviour of these three bits is also not consistent between all Linux clones.

setuid (4xxx)

  • Binary executable: Executable runs as the file-owner user, independent of who launches the process

setgid (2xxx)

  • Binary executable: Executable runs as the file-owner user, independent of who launches the process
  • Directory: New files and directories inherit the group of directory

sticky (1xxx)

  • Executable: Retain file in swap after exec (obsolete)
  • Directories: Only the owner and root can delete or rename files. (Otherwise, the directory owner can delete or move files)

How they are displayed

Command-line tools like ls encode the information in their usual output. The usual x to indicate an executable is dropped and replaced with s or t. If the file is not executable, S or T is used.

  • Executable files:
    0xxx = ... ... ..T
    1xxx = ... ... ..T
    2xxx = ... ..S ...
    4xxx = ..S ... ...
    
  • Non-executable files:
    0xxx = ... ... ..t
    1xxx = ... ... ..t
    2xxx = ... ..s ..t
    4xxx = ..s ... ..t