Linux File Permissions: chmod, Special Bits, umask, ACLs, and Attributes

Linux enforces a multi-user permission model to ensure security and isolation across system resources. This guide covers basic octal and symbolic permissions (chmod), directory permission mechanics, special permission bits (SUID, SGID, Sticky Bit), default permissions (umask), POSIX Access Control Lists (setfacl/getfacl), and filesystem attributes (chattr).


⚡ Quick Dive

Permission Quick Reference & Calculator

Permission Octal Binary On Files On Directories
Read (r) 4 100 View file content List directory contents (ls)
Write (w) 2 010 Modify/overwrite file content Create, delete, rename files inside
Execute (x) 1 001 Run as executable program/script Enter/traverse directory (cd) and access inodes
None (-) 0 000 No access granted No access granted

Common Permission Recipes

Octal Symbolic Target Usage
644 rw-r--r-- Standard public files (HTML, images, configs, text files)
755 rwxr-xr-x Standard directories and public executable scripts/binaries
600 rw------- Private sensitive files (SSH private keys, .env credentials)
700 rwx------ Private user directories (~/.ssh, root private folders)
1777 rwxrwxrwt Shared temporary directories with Sticky Bit (/tmp)

Essential One-Liners

# Make a shell script executable by the owner only
chmod u+x deploy.sh

# Set standard permissions recursively: directories 755, files 644
find /var/www -type d -exec chmod 755 {} +
find /var/www -type f -exec chmod 644 {} +

# Lock a sensitive file against modification even by root
sudo chattr +i /etc/resolv.conf

📖 Extended Guide

1. The Linux Permission Architecture

Permissions in Linux are divided into three security classes, evaluated in order:

File Mode: - r w x r - x r - -
           │ └──┬┘ └──┬┘ └──┬┘
           │    │     │     └─ Others (World / Everyone else) [o]
           │    │     └─────── Owning Group [g]
           │    └───────────── Owning User [u]
           └────────────────── File Type (- file, d directory, l symlink)

Permission Evaluation Rules

  1. If the current user matches the Owner UID, the user permissions apply.
  2. If the user belongs to the Owning GID, group permissions apply.
  3. Otherwise, the Others permissions apply.

2. Files vs. Directories Permission Nuances

Understanding how permissions apply to directories is critical:

  • Read (r) on Directory: Allows listing names of files inside (ls). Without x, you cannot view file metadata (size, dates) or enter the directory.
  • Write (w) on Directory: Allows adding, removing, and renaming files inside the directory, even if the user does not own or have write access to the individual files inside.
  • Execute (x) on Directory: Allows traversing the directory (cd) and referencing inode paths within it.

[!WARNING] Giving write access (w) on a directory allows users to delete files inside it, regardless of the individual file's permissions!


3. chmod — Changing Permissions

Symbolic Notation

Format: chmod [who][action][permission] file

  • Who: u (user/owner), g (group), o (others), a (all / everyone).
  • Action: + (grant), - (revoke), = (set exact).
  • Permission: r, w, x, s, t.
# Add execute to user, remove write from group and others
chmod u+x,go-w build.sh

# Set exact permissions: user read/write, group read, others none
chmod u=rw,g=r,o= config.yml

Numeric (Octal) Notation

Combine octal values for User, Group, and Others:

  • Owner = r + w (4 + 2 = 6)
  • Group = r (4)
  • Others = r (4)
  • Command: chmod 644 file.txt

4. Special Permission Bits: SUID, SGID, and Sticky Bit

Linux provides three special permission bits that precede the standard 3-digit octal triplet:

Special Bit (4xxx / 2xxx / 1xxx) + Owner (7xx) + Group (x5x) + Others (xx5)
Special Bit Octal Position On Files On Directories
SUID (Set UID) 4000 u+s (represented as s/S in owner execute) Runs process with permissions of the file owner (e.g., /usr/bin/passwd) No effect on most Linux kernels
SGID (Set GID) 2000 g+s (represented as s/S in group execute) Runs process with permissions of the group owner New files created inherit parent directory's group
Sticky Bit 1000 o+t (represented as t/T in others execute) No effect on regular files Only the file owner or root can delete/rename files inside (/tmp)
# Enable SGID on shared directory for team collaboration
chmod 2775 /var/shared/devs/

# Set Sticky Bit on shared directory
chmod +t /shared/uploads/
# OR
chmod 1777 /shared/uploads/

5. Default Permissions & umask

The umask (user file-creation mask) determines default permissions for newly created files and directories.

  • Base Directory Mode: 0777 (rwxrwxrwx)
  • Base File Mode: 0666 (rw-rw-rw-)

Formula

Default Directory Permissions = 0777 - umask
Default File Permissions      = 0666 - umask (clearing execute bits)
# View active umask in octal
$ umask
0022

# Default file with 0022:  666 - 022 = 644 (rw-r--r--)
# Default dir with 0022:   777 - 022 = 755 (rwxr-xr-x)

# Set restrictive umask for active shell
umask 0077
# New files will have 600, new directories 700

6. Extended Permissions: POSIX Access Control Lists (ACLs)

When traditional user/group/others model is too restrictive, ACLs allow granting permissions to specific individual users and groups:

# View ACLs of a file or directory
getfacl /var/log/app/

# Grant read/write access to user 'alice' without changing owner
setfacl -m u:alice:rw /var/log/app/audit.log

# Grant read access to group 'auditors'
setfacl -m g:auditors:r /var/log/app/audit.log

# Set default ACLs on directory (automatically inherited by new files)
setfacl -d -m u:alice:rwx /var/log/app/

# Remove all ACLs and revert to standard POSIX permissions
setfacl -b /var/log/app/audit.log

7. File Immutability & Attributes: chattr and lsattr

Filesystem attributes work at the filesystem driver level (e.g., ext4, xfs) and override standard file permissions (even for root):

  • +i (Immutable): Cannot be modified, deleted, overwritten, renamed, or linked.
  • +a (Append-Only): File can only be opened in append mode (ideal for security log files).
# Make critical file immutable
sudo chattr +i /etc/shadow

# Inspect attributes
$ lsattr /etc/shadow
----i---------e---- /etc/shadow

# Remove immutable flag
sudo chattr -i /etc/shadow

# Make log file append-only
sudo chattr +a /var/log/secure_events.log