Linux File Permissions and Ownership


  • Description: How Unix file permissions and ownership work — the rwx mode triad, octal notation, chmod / chown / chgrp usage, special bits (setuid, setgid, sticky), umask defaults, and a brief pointer to POSIX ACLs.
  • My Notion Note ID: K2B-3-3
  • Created: 2020-06-03
  • Updated: 2026-05-19
  • License: Reuse is very welcome. Please credit Yu Zhang and link back to the original on yuzhang.io

Table of Contents


1. The Permission Model

  • Three identity classes:
    • u (user) — the file's owner
    • g (group) — the file's group
    • o (other) — everyone else
    • a (all) — shorthand for ugo
  • Three permissions per class:
    • r read — list directory entries, or read file content
    • w write — modify file content; for a directory, create/delete/rename entries
    • x execute — run the file as a program; for a directory, traverse into it (look up entries by name)
  • Permissions on directories have surprising semantics:
    • r without x → you can ls the dir but cannot stat or read any file inside.
    • x without r → you can cd in and access named files but cannot ls.
    • w requires x to be meaningful — you need traversal to actually create or delete entries.

2. Reading ls -l Output

-rwxr-xr-- 1 alice devs  4096 May 10 12:34 build.sh
drwxr-x--- 3 alice devs   128 May 10 12:35 src
lrwxrwxrwx 1 alice devs    11 May 10 12:36 link -> build.sh
  • First character — file type: - regular, d directory, l symlink, c/b char/block device, p named pipe, s socket.
  • Next nine — three rwx triads for u, g, o.
  • Owner / group columns — names from /etc/passwd and /etc/group.
  • Symlinks are usually shown as lrwxrwxrwx — symlink mode is ignored; permissions of the target are what matter.

3. chmod — Symbolic Mode

  • chmod [OPTION]... MODE FILE...
  • Symbolic form: [ugoa...][+-=][rwxX]...[,...]
    • Class: u, g, o, a (default if you omit it is a masked by umask).
    • Operator: + add, - remove, = set exactly.
    • Perm: r, w, x. Plus X — "execute only if it's a directory or already has any x bit set" — perfect for chmod -R u+rwX,go+rX on a mixed tree.
  • Examples:
    • chmod u+x build.sh — make executable for owner only.
    • chmod go-w secrets.txt — drop write for group and other.
    • chmod a=r README — exactly r--r--r-- for everyone.
    • chmod u+rwx,g+rx,o= dir — combine multiple clauses with commas.
  • Useful options:
    • -R, --recursive — apply to a tree. Combine with X to keep dir traversal sensible.
    • --reference=FILE — copy permissions from another file.
    • -v — print every change; -c — print only actual changes.

4. chmod — Octal Mode

  • Four octal digits: SUGO, where S is the special-bits digit (often 0 and omitted) and U, G, O are the rwx triads.
  • Per-triad sum: r=4, w=2, x=1.
    • 7 = rwx, 6 = rw-, 5 = r-x, 4 = r--, 0 = ---.
  • Common modes worth memorizing:
Octal Symbolic Typical use
644 rw-r--r-- regular file readable by all
600 rw------- private file (SSH keys, .netrc)
755 rwxr-xr-x executable / world-readable dir
750 rwxr-x--- group-shared executable / dir
700 rwx------ private dir (~/.ssh)
4755 rwsr-xr-x setuid root binary (/usr/bin/sudo)
2775 rwxrwsr-x setgid dir for shared projects
1777 rwxrwxrwt sticky world-writable dir (/tmp)

5. Special Bits: setuid, setgid, sticky

The leading digit in the 4-digit octal (S = setuid*4 + setgid*2 + sticky*1):

  • setuid (4) on an executable → process runs as the file's owner regardless of who launched it. The classic example is passwd: the program needs to edit /etc/shadow, which is root-only, so it's 4755 and owned by root. Setuid on shell scripts is ignored on Linux for security reasons.
  • setgid (2):
    • On an executable → runs with the file's group identity.
    • On a directory → new files inside inherit the directory's group, not the creator's primary group. This is how shared project directories stay consistent.
  • sticky (1) on a directory → only a file's owner (or root) may delete or rename it, even if the directory is world-writable. /tmp is the canonical case (1777).
  • Symbolically: chmod u+s, chmod g+s, chmod +t. Visible in ls -l as s (in place of x) and t (sticky in the world triad). Capital S/T mean "the special bit is set but the underlying x is not" — usually a mistake.

6. chown and chgrp

  • chown [OPTION]... [OWNER][:[GROUP]] FILE... — change owner, group, or both.
    • chown alice file — owner only.
    • chown alice:devs file — owner and group.
    • chown :devs file — group only (equivalent to chgrp devs file).
    • chown alice: file — owner alice, group set to alice's primary group.
  • chgrp [OPTION]... GROUP FILE... — change group only. Subset of chown.
  • Options shared by both:
    • -R, --recursive — apply to a tree.
    • -h — operate on the symlink itself, not its target. Default is to follow.
    • --reference=FILE — copy ownership from another file.
    • --from=CURRENT_OWNER[:CURRENT_GROUP] — only change if the current owner/group matches (safe rewrites).
  • Only root can change a file's owner. Non-root can only change a file's group, and only to a group the user belongs to.

7. umask — Default Permissions

  • umask is the bits that are turned off when new files and directories are created. Default mode would be 666 for files and 777 for directories; the actual mode is (default) & ~umask.
  • Common umasks:
    • 022 → files 644, dirs 755. Most distros' default.
    • 002 → files 664, dirs 775. Group-writable; for shared dev machines.
    • 077 → files 600, dirs 700. Privacy-conscious.
  • Set in ~/.bashrc / ~/.zshrc / /etc/profile for persistent change. umask 022 to inspect, umask -S to print symbolically.

8. ACLs (Brief)

When the ugo triad isn't enough (multiple groups need different access, or per-user grants), POSIX ACLs give per-principal entries.

  • Check: getfacl FILE — shows the ACL, including the standard ugo bits.
  • Set: setfacl -m u:bob:r file (give bob read), setfacl -m g:auditors:rx dir.
  • Mask entry caps the maximum permission grantable to named users/groups.
  • Default ACLs on a directory (setfacl -d -m ...) act like a stickier setgid: new entries inherit the ACL.
  • ls -l shows a trailing + in the mode field when a file has an ACL: -rw-r--r--+.
  • Not all filesystems support ACLs — most modern Linux setups (ext4, xfs, btrfs) do; FAT/exFAT do not.

9. References

  • man 1 chmod, man 1 chown, man 1 chgrp, man 1 umask, man 5 acl
  • GNU coreutils manual — info coreutils → "File permissions"
  • POSIX ACL — man getfacl, man setfacl