File Permissions and ACLs
Unix Permission Model
Section titled “Unix Permission Model”Every file and directory on a Linux system carries a set of permission bits that control which users Can read, write, or execute it. The kernel enforces these permissions during every file system Operation.
Permission Bits
Section titled “Permission Bits”Each file has three categories of permissions, each with three bits:
| Category | Read (r) | Write (w) | Execute (x) |
|---|---|---|---|
| Owner (u) | Read file contents / List directory entries | Modify file / Create/delete directory entries | Run file / Enter directory |
| Group (g) | Same as owner for group members | Same | Same |
| Other (o) | Same for everyone else | Same | Same |
Octal Notation
Section titled “Octal Notation”| Octal | Binary | Permission |
|---|---|---|
| 0 | 000 | --- |
| 1 | 001 | —x |
| 2 | 010 | -w- |
| 3 | 011 | -wx |
| 4 | 100 | r— |
| 5 | 101 | r-x |
| 6 | 110 | rw- |
| 7 | 111 | rwx |
Common permission sets:
| Octal | Meaning | Use Case |
|---|---|---|
| 755 | rwxr-xr-x | Executables, directories |
| 644 | rw-r—r— | Regular files |
| 700 | rwx------ | Private scripts |
| 600 | rw------- | SSH keys, config files |
| 400 | r-------- | Read-only secrets |
| 711 | rwx—x—x | Public directories (listable only by owner) |
Viewing Permissions
Section titled “Viewing Permissions”# Long listing shows permissions, owner, groupls -la /etc/passwd# -rw-r--r-- 1 root root 2847 Jan 15 10:30 /etc/passwd
# Numeric viewstat -c "%a %n' /etc/passwd# 644 /etc/passwd
stat -c '%A %U:%G %n' /etc/passwd# -rw-r--r-- root:root /etc/passwd
# Full stat outputstat /etc/passwdDirectory Permissions
Section titled “Directory Permissions”Directory permissions have different semantics than file permissions:
| Permission | File | Directory |
|---|---|---|
| r | Read file contents | List filenames (requires x) |
| w | Modify file contents | Create/delete/rename files (requires x) |
| x | Execute as a program | Enter directory (cd), access inode information |
To list directory contents: r + xTo create/delete files: w + xTo access a file inside: x on every parent directory
Without x on a directory: - Cannot cd into it - Cannot stat files inside it - Cannot read files even if they are 644
Without r on a directory: - Cannot list files (ls fails) - But can access files if you know their names (cat dir/file works)# Example: a directory where you can access files but not list themmkdir secret && chmod 711 secretecho "hidden content" > secret/data.txtchmod 644 secret/data.txt
# Other users cannot list the directoryls secret/ # Permission denied
# But can read the file if they know the namecat secret/data.txt # works!chmod — Change Permissions
Section titled “chmod — Change Permissions”Symbolic Mode
Section titled “Symbolic Mode”# Format: who + action + permission# who: u (owner), g (group), o (other), a (all)# action: + (add), - (remove), = (set exactly)# permission: r, w, x, X, s, t, u, g, o
# Add execute for ownerchmod u+x script.sh
# Remove write for group and otherchmod go-w file.txt
# Set exact permissionschmod u=rwx,g=rx,o= file.txt
# Recursively set directories to 755, files to 644chmod -R a=rX,u+w . # X sets x only if already x for any category, or if directoryfind . -type d -exec chmod 755 {} +find . -type f -exec chmod 644 {} +
# Reference mode (copy permissions from another file)chmod --reference=reference.txt target.txtNumeric Mode
Section titled “Numeric Mode”chmod 755 script.sh # rwxr-xr-xchmod 600 id_rsa # rw-------chmod 644 config.conf # rw-r--r--chmod 1777 /tmp # rwxrwxrwt (sticky bit)chmod 4755 /usr/bin/sudo # rwsr-xr-x (setuid)chown and chgrp
Section titled “chown and chgrp”# Change ownerchown user file.txt
# Change groupchgrp group file.txt
# Change both owner and groupchown user:group file.txt
# Change owner, keep groupchown user: file.txt
# Change group only (shortcut)chown :group file.txt
# Recursivechown -R user:group /var/www/html/
# Referencechown --reference=ref.txt target.txtOnly root can change the owner of a file. The owner can change the group to any group they are a Member of. This is enforced by the kernel: the chown(2) system call checks capable(CAP_CHOWN).
The umask (user file creation mask) determines the default permissions for newly created files and Directories. It is a mask that is subtracted from the maximum permissions:
| Creation | Maximum | Applied as | umask 0022 result |
|---|---|---|---|
| Regular file | 0666 | 0666 & ~022 = 0644 | rw-r—r— |
| Directory | 0777 | 0777 & ~022 = 0755 | rwxr-xr-x |
# View current umaskumask # outputs octal (e.g., 0022)umask -S # symbolic form (u=rwx,g=rx,o=rx)
# Set umaskumask 0027 # owner: rwx, group: rx, other: ---umask 0077 # owner only (private)
# Common umask values# 0022 — world-readable (default on most systems)# 0027 — group-readable, no world access# 0077 — private (SSH, PGP directories)
# Set in profileecho 'umask 0027' >> ~/.profileThe kernel checks ACLs if they exist on the file. The check order is: owner, named users (most Specific first), owning group or named groups, mask, other. The first matching entry that grants or Denies the requested access determines the result. The mask limits the maximum effective permissions For all named users, named groups, and the owning group.
Permission Check Summary
Section titled “Permission Check Summary”1. If process is root (UID 0): a. If CAP_DAC_OVERRIDE is in effective set: grant b. For directories: grant if at least one execute bit is set c. For files: grant read/write, deny execute unless at least one execute bit is set
2. If ACLs exist: a. Check if effective UID matches file owner -> use owner permissions b. Check named user entries -> use matching entry (masked) c. Check if effective GID or supplementary groups match file group -> use group (masked) d. Check named group entries -> use matching entry (masked) e. Use other permissions
3. If no ACLs: a. Owner match -> use owner permissions b. Group match -> use group permissions c. Other -> use other permissionsfind with -perm
Section titled “find with -perm”# Find files with exactly 644 permissionsfind /etc -perm 644
# Find files with at least the specified bits setfind /etc -perm -644 # 644 or higher (744, 755, 777, etc.)
# Find files with any of the specified bits setfind /etc -perm /644 # any file with r for any category
# Find world-writable filesfind / -perm -o+w -type f 2>/dev/null
# Find files without any group or other permissionsfind /etc -perm /600 # only owner has any permissions
# Find setuid filesfind / -perm -4000 -type f 2>/dev/null
# Find setgid filesfind / -perm -2000 -type f 2>/dev/null
# Find sticky bit directoriesfind / -perm -1000 -type d 2>/dev/null
# Find files with specific octal and group ownershipfind /var -perm 640 -group www-data
# Find and fix permissionsfind /var/www -type f -exec chmod 644 {} +find /var/www -type d -exec chmod 755 {} +SUID/SGID Security Risks
Section titled “SUID/SGID Security Risks”# Find all setuid root binariesfind / -perm -4000 -user root -type f 2>/dev/null
# Check for writable setuid directoriesfind / -perm -2000 -type d -perm -o+w 2>/dev/null
# Find setuid binaries not owned by rootfind / -perm -4000 ! -user root -type f 2>/dev/null
# Audit setuid binaries that are writable by non-rootfind / -perm -4000 -type f ! -perm -u+s -writable 2>/dev/null