Unix File Permissions Decoded
Unix permissions pack into 12 bits: nine for owner/group/other rwx plus three for setuid, setgid, and the sticky bit, displayed as four octal digits. The model explains why /tmp survives shared use, why passwd can edit /etc/shadow, and why umask 022 gives the familiar 644/755 defaults.
Every file on a Unix-like system carries a 12-bit permission word, usually displayed as four octal digits like 0755 or 4755. The low nine bits split into three triplets — owner (user), group, and other — and each triplet holds read (r=4), write (w=2), and execute (x=1) flags. Adding the values within a triplet produces one octal digit, so rwxr-xr-x reads as 7-5-5 = 755. The three high bits hold the setuid, setgid, and sticky bit flags, weighted 4-2-1 in the leading digit. A chmod argument of 4755 therefore means setuid plus rwxr-xr-x. The model originated in early AT&T Unix and was carried into every POSIX descendant — Linux, the BSDs, macOS — so `chmod` arguments work almost everywhere; richer schemes like the ZFS (Zettabyte File System) ACL model layer on top. Reading `ls -l` left to right: the first character names the file type (`-` regular, `d` directory, `l` symlink, `c`/`b` device, `p` named pipe, `s` socket). The next nine characters are the rwx triplets. Common patterns include 755 for executables and directories, 644 for ordinary files, 600 for private keys, and 700 for personal home directories. When a special bit replaces the execute slot, the listing shows `s` or `t`; when execute is unset underneath, the letter capitalises to `S` or `T`. The three special bits change semantics meaningfully. Setuid on an executable makes the process run with the file owner's effective UID — this is how `/usr/bin/passwd` lets ordinary users edit `/etc/shadow` without granting them root. Because the bit hands attackers a ready-made privilege boundary, misconfigured setuid binaries are a classic privilege escalation vector. Setgid behaves similarly for the group, and on a directory it makes new entries inherit the directory's group — the standard trick for shared project folders. The sticky bit on a world-writable directory like `/tmp` restricts deletion and rename to each file's owner, preventing users from clobbering each other's scratch files. Default permissions for newly created files come from the process's umask, a subtractive mask: the kernel clears any bit set in the umask from the requested mode. A umask of 022 yields 644 for files (666 base) and 755 for directories (777 base) — readable by everyone, writable only by the owner. Stricter sites use 027 or 077. When the nine-bit model is too coarse, POSIX ACLs stored as extended attributes (xattr) give per-user and per-group entries, managed with `setfacl` and `getfacl`. Common foot-guns: `chmod 777` makes a file world-writable and is almost never the right fix; forgetting `chmod +x` leaves a script unrunnable; and `chmod -R` recursively flattens execute bits across directories and regular files alike — use `find ... -type d` to scope it.