env.dev

Linux File Permissions: chmod, chown, umask & ACLs

Master Linux file permissions including chmod, chown, umask, sticky bit, SUID/SGID, and Access Control Lists.

Last updated:

Linux file permissions control who can read, write, and execute files and directories. Every file has an owner, a group, and a set of permission bits. Understanding chmod, chown, umask, and special bits (SUID, SGID, sticky) is fundamental to Linux system administration and application security.

How Do Linux Permissions Work?

Each file has three permission groups — owner (u), group (g), and others (o) — and three permission types — read (r), write (w), and execute (x). The ls -l command displays them as a 10-character string.

Reading permission strings
-rwxr-xr-- 1 alice devs 4096 Apr 12 10:00 deploy.sh
│└┬┘└┬┘└┬┘
│ │  │  └── others:  r-- (read only)
│ │  └───── group:   r-x (read + execute)
│ └──────── owner:   rwx (read + write + execute)
└────────── file type: - (regular file), d (directory), l (symlink)

Permission values:
  r (read)    = 4
  w (write)   = 2
  x (execute) = 1

Octal sum per group:
  rwx = 4+2+1 = 7
  r-x = 4+0+1 = 5
  r-- = 4+0+0 = 4
  → 754 in octal notation

How Do You Use chmod?

chmod changes file permissions using either octal notation (numeric) or symbolic notation (letters). Octal is more concise; symbolic is more readable for targeted changes.

chmod with octal notation
# Common octal permission values
chmod 755 script.sh    # rwxr-xr-x — executable by everyone, writable by owner
chmod 644 config.yaml  # rw-r--r-- — readable by everyone, writable by owner
chmod 600 id_ed25519   # rw------- — owner only (SSH private keys)
chmod 700 .ssh/        # rwx------ — owner only (SSH directory)
chmod 666 shared.txt   # rw-rw-rw- — readable/writable by everyone (rarely correct)
chmod 400 secrets.env  # r-------- — read-only by owner

# Recursive — apply to all files and directories
chmod -R 755 /var/www/html/
chmod with symbolic notation
# Symbolic format: [ugoa][+-=][rwxXsst]
# u=owner, g=group, o=others, a=all

# Add execute permission for the owner
chmod u+x deploy.sh

# Remove write permission from group and others
chmod go-w config.yaml

# Set exact permissions — owner rw, group r, others nothing
chmod u=rw,g=r,o= secret.conf

# Add execute only to directories (capital X)
chmod -R a+X /var/www/    # Adds execute to dirs but not files

# Make a file immutable to group write
chmod g-w important.log

# Multiple operations in one command
chmod u+rwx,g+rx,o-rwx deploy.sh

How Do You Change Ownership with chown?

chown changes the owner and/or group of a file. Only root can change the owner; regular users can change the group to one they belong to.

chown examples
# Change owner
sudo chown alice deploy.sh

# Change owner and group
sudo chown alice:devs deploy.sh

# Change group only (note the colon)
sudo chown :devs deploy.sh

# Alternative: change group with chgrp
sudo chgrp devs deploy.sh

# Recursive — change ownership of all contents
sudo chown -R www-data:www-data /var/www/html/

# Common pattern: set web server ownership
sudo chown -R nginx:nginx /usr/share/nginx/html/

What Is umask and How Does It Work?

umask sets the default permission mask for newly created files and directories. It subtracts permissions from the maximum defaults (666 for files, 777 for directories).

umask explained
# View current umask
umask         # e.g., 0022
umask -S      # symbolic: u=rwx,g=rx,o=rx

# How umask works:
#   Files:       666 - 022 = 644 (rw-r--r--)
#   Directories: 777 - 022 = 755 (rwxr-xr-x)

# Common umask values
umask 022   # Default — files 644, dirs 755 (readable by all)
umask 027   # Restrictive — files 640, dirs 750 (no access for others)
umask 077   # Private — files 600, dirs 700 (owner only)

# Set in shell profile (~/.bashrc or ~/.zshrc) for persistence
echo 'umask 027' >> ~/.bashrc

# Temporary umask for a single command
(umask 077 && touch secret.key)  # Created with 600 permissions

What Are SUID, SGID, and Sticky Bit?

Special permission bits modify how files and directories behave beyond the standard read/write/execute model.

BitOctalOn FilesOn Directories
SUID4000Runs as file owner (e.g., passwd runs as root)No effect
SGID2000Runs as file groupNew files inherit directory's group
Sticky1000No effect (modern Linux)Only file owner can delete their files
Special permission bits
# SUID — the 's' in owner execute position
chmod u+s /usr/bin/passwd
ls -l /usr/bin/passwd
# -rwsr-xr-x  ← 's' means SUID is set

# SGID on a directory — new files inherit group
chmod g+s /shared/projects/
ls -ld /shared/projects/
# drwxrwsr-x  ← 's' in group execute position

# Sticky bit — commonly set on /tmp
chmod +t /tmp/
ls -ld /tmp/
# drwxrwxrwt  ← 't' in others execute position

# Using octal — prepend the special bit
chmod 4755 program       # SUID + rwxr-xr-x
chmod 2775 shared-dir/   # SGID + rwxrwxr-x
chmod 1777 /tmp/         # Sticky + rwxrwxrwx

# Find all SUID files on the system (security audit)
find / -perm -4000 -type f 2>/dev/null

How Do ACLs Extend Standard Permissions?

POSIX Access Control Lists (ACLs) let you grant permissions to specific users or groups beyond the single owner/group model. They are essential when multiple teams need different access levels to the same directory.

ACL management with getfacl and setfacl
# View ACLs on a file
getfacl project/

# Grant read+write to a specific user
setfacl -m u:bob:rw project/report.txt

# Grant read to a specific group
setfacl -m g:auditors:r project/report.txt

# Set default ACL on a directory (inherited by new files)
setfacl -d -m g:devs:rwx /shared/code/

# Remove a specific ACL entry
setfacl -x u:bob project/report.txt

# Remove all ACLs (revert to standard permissions)
setfacl -b project/report.txt

# Recursive — apply ACL to all existing contents
setfacl -R -m g:devs:rwx /shared/code/

# The '+' in ls -l indicates ACLs are present
ls -l report.txt
# -rw-rw-r--+ 1 alice devs 1024 Apr 12 10:00 report.txt

Note: ACLs require a filesystem that supports them (ext4, XFS, Btrfs). Mount with acl option if not enabled by default. The effective mask (mask::rwx) limits the maximum ACL permissions — check it when permissions seem wrong despite correct ACL entries.

Key Takeaways

  • • Permissions are expressed as three groups (owner, group, others) with read (4), write (2), execute (1)
  • • Use chmod 755 for executables, 644 for config files, 600 for secrets
  • umask 022 is the standard default — use 027 or 077 for tighter security
  • • SGID on directories ensures new files inherit the directory's group ownership
  • • Sticky bit on shared directories prevents users from deleting each other's files
  • • ACLs extend the owner/group model to support fine-grained per-user and per-group permissions
  • • Audit SUID files regularly — they run with elevated privileges and are a common attack vector

Frequently Asked Questions

What does chmod 755 mean?

Owner gets read+write+execute (7), group gets read+execute (5), others get read+execute (5). In symbolic form: rwxr-xr-x. This is the standard permission for directories and executable scripts.

What is the sticky bit?

The sticky bit (chmod +t) on a directory prevents users from deleting files they do not own. The /tmp directory uses this: drwxrwxrwt. Set with chmod 1777 or chmod +t.

What is umask?

umask sets default permissions for new files and directories. It specifies which permissions to remove. umask 022 means new files get 644 (666-022) and directories get 755 (777-022).

Was this helpful?

Stay up to date

Get notified about new guides, tools, and cheatsheets.