Loading...

Linux File Permissions: chmod, chown, umask, SUID, and ACLs Explained

Back to blog
LinuxPermissionsSecuritySystem Administration

Linux File Permissions: chmod, chown, umask, SUID, and ACLs Explained

Master Linux file permissions including chmod, chown, umask, special permissions (SUID, SGID, sticky bit), and access control lists (ACLs) with practical examples.

11 min read

Linux File Permissions: chmod, chown, umask, SUID, and ACLs Explained

File permissions are fundamental to Linux security and system administration. Understanding how to read, modify, and manage permissions is crucial for controlling file access and protecting sensitive data.

Understanding Basic Permissions

Every file and directory in Linux has three types of permissions: read (r), write (w), and execute (x).

Permission Notation

# View file permissions
ls -l /home/john/file.txt
# -rw-r--r-- 1 john users 1024 Jan 23 10:00 file.txt
 
# Breaking down the permissions:
# -       = file type (- = regular file, d = directory, l = symlink)
# rw-     = owner permissions (read, write, no execute)
# r--     = group permissions (read only)
# r--     = others permissions (read only)
# 1       = number of hard links
# john    = owner
# users   = group
# 1024    = file size in bytes
# Jan 23 10:00 = modification time
# file.txt = filename

Permission Values

Symbol Octal Meaning
r 4 Read (view contents)
w 2 Write (modify contents)
x 1 Execute (run file or enter directory)

Three Categories

  • Owner (user): The user who owns the file
  • Group: Members of the file's group
  • Others: Everyone else on the system

chmod - Change File Mode

Modify file and directory permissions.

Symbolic Mode

# Add execute permission for owner
chmod u+x script.sh
ls -l script.sh
# -rwxr--r-- 1 john users ...
 
# Add write permission for group
chmod g+w document.txt
ls -l document.txt
# -rw-rw-r-- 1 john users ...
 
# Add read permission for others
chmod o+r secret.txt
ls -l secret.txt
# -rw-r--r-- 1 john users ...
 
# Remove write permission from group
chmod g-w document.txt
ls -l document.txt
# -rw-r--r-- 1 john users ...
 
# Remove execute permission for all
chmod a-x script.sh
ls -l script.sh
# -rw-r--r-- 1 john users ...
 
# Add permissions for multiple categories
chmod u+x,g+r,o-r script.sh
 
# Set specific permissions (replace existing)
chmod u=rwx,g=rx,o= script.sh
# Owner: read, write, execute
# Group: read, execute
# Others: no permissions

Octal Mode

# Octal permissions: sum the values for each category
# Owner=7 (4+2+1=rwx), Group=5 (4+0+1=r-x), Others=0 (-----)
chmod 750 script.sh
ls -l script.sh
# -rwxr-x--- 1 john users ...
 
# Common permission combinations
chmod 644 file.txt          # rw-r--r-- (readable by all, writable by owner)
chmod 755 directory/        # rwxr-xr-x (standard directory permissions)
chmod 600 private.txt       # rw------- (readable/writable by owner only)
chmod 700 private_dir/      # rwx------ (accessible by owner only)
chmod 777 shared.txt        # rwxrwxrwx (writable by everyone - dangerous!)
 
# Recursive permission change
chmod -R 755 /home/john/public_html/
chmod -R 644 /home/john/public_html/*.html
 
# View directory permissions
ls -ld /home/john/
# drwxr-xr-x 1 john users ...

Symbolic Mode Operators

# + = add permission
# - = remove permission
# = = set exactly (remove others)
 
# Add to owner and group
chmod ug+rw file.txt
 
# Add to owner, group, and others
chmod a+x script.sh
 
# Set exact permissions for owner
chmod u=rwx script.sh      # Only rwx for owner, remove existing
chmod u=rw script.sh       # Only rw for owner
 
# Remove all permissions
chmod 000 file.txt
chmod ugo-rwx file.txt
 
# Standard web permissions
chmod u=rwx,g=rx,o=rx directory/  # 755 in octal
chmod u=rw,g=r,o=r file.txt       # 644 in octal

chown - Change Owner and Group

Modify file and directory ownership.

# Change owner
sudo chown john file.txt
ls -l file.txt
# -rw-r--r-- 1 john users ...
 
# Change owner and group
sudo chown john:developers file.txt
ls -l file.txt
# -rw-r--r-- 1 john developers ...
 
# Change only the group
sudo chown :developers file.txt
sudo chgrp developers file.txt  # Alternative
 
# Change owner recursively
sudo chown -R john /home/john/projects/
sudo chown -R john:developers /var/www/html/
 
# Change group recursively
sudo chgrp -R developers /home/john/projects/
 
# Change owner for multiple files
sudo chown john:developers file1.txt file2.txt file3.txt
 
# Use chown with find for complex operations
sudo find /home/john -type f -exec chown john:developers {} \;
 
# Preserve symbolic links (follow symlinks)
sudo chown -L john file.txt
 
# Reference permissions from another file
touch reference.txt
chmod 755 reference.txt
chmod --reference=reference.txt file.txt
ls -l file.txt

chgrp - Change Group

Modify only the group ownership.

# Change group
sudo chgrp developers file.txt
ls -l file.txt
# -rw-r--r-- 1 john developers ...
 
# Change group recursively
sudo chgrp -R developers /home/john/projects/
 
# Change group for multiple files
sudo chgrp users file1.txt file2.txt file3.txt
 
# View available groups
cat /etc/group | head -20
# root:x:0:
# users:x:100:
# developers:x:1001:john,sarah
 
# Check which groups a user belongs to
groups john
# john : john developers users
 
# Add user to a group
sudo usermod -aG developers john
 
# List group members
grep developers /etc/group
# developers:x:1001:john,sarah,mike

umask - Default Permissions

Sets default permissions for new files and directories.

Understanding umask

umask determines which permissions are removed from the default permissions (666 for files, 777 for directories).

# View current umask
umask
# 0022
 
# Understanding the calculation:
# Default file permissions: 666 (rw-rw-rw-)
# umask: 022 (removes write from group and others)
# Result: 644 (rw-r--r--)
 
# Default directory permissions: 777 (rwxrwxrwx)
# umask: 022
# Result: 755 (rwxr-xr-x)
 
# Create a test file to see umask effect
touch test.txt
ls -l test.txt
# -rw-r--r-- 1 john users ...
 
# Create a directory to see umask effect
mkdir test_dir
ls -ld test_dir
# drwxr-xr-x 1 john users ...

Setting umask

# Set umask for current session
umask 0077
# Now new files: 600 (rw-------)
# Now new dirs:  700 (rwx------)
 
# Verify new permissions
touch private.txt
ls -l private.txt
# -rw------- 1 john users ...
 
# Reset to default
umask 0022
 
# Set umask permanently in shell config
echo "umask 0077" >> ~/.bashrc
source ~/.bashrc
 
# Common umask values:
# 0022 = default (files: 644, dirs: 755)
# 0027 = secure (files: 640, dirs: 750)
# 0077 = very restrictive (files: 600, dirs: 700)
# 0002 = permissive (files: 664, dirs: 775)

Special Permissions

SUID (Set User ID)

Allows a file to be executed with the permissions of the owner (usually root).

# Identify SUID bit: 's' in owner execute position
ls -l /usr/bin/sudo
# -rwsr-xr-x 1 root root ...
#     ^ = SUID bit
 
# Set SUID
chmod u+s executable.sh
ls -l executable.sh
# -rwsr-xr-x 1 john users ...
 
# Octal notation (4000)
chmod 4755 executable.sh
# Same as: chmod u+s,u=rwx,g=rx,o=rx
 
# Remove SUID
chmod u-s executable.sh
 
# Security considerations
# SUID is dangerous if not properly used
# Only use on well-tested, security-audited programs
sudo find / -perm -4000 2>/dev/null  # Find all SUID files

SGID (Set Group ID)

Allows file to execute with the group's permissions (for files) or makes new files inherit the directory's group (for directories).

# Identify SGID bit: 's' in group execute position
ls -l /usr/local/bin/groupcmd
# -rwxr-sr-x 1 root developers ...
#        ^ = SGID bit
 
# Set SGID on file
chmod g+s executable.sh
ls -l executable.sh
# -rwxr-sr-x 1 john users ...
 
# Set SGID on directory (files inherit directory group)
chmod g+s shared_directory/
mkdir shared_directory/newfile  # Inherits group from directory
 
# Octal notation (2000)
chmod 2755 executable.sh
 
# Practical example: shared project directory
mkdir /opt/project
sudo chown :developers /opt/project
sudo chmod 2775 /opt/project
# All files created here will belong to 'developers' group
 
# Remove SGID
chmod g-s executable.sh

Sticky Bit

On directories, prevents deletion of files by non-owners (important for /tmp).

# Identify sticky bit: 't' in others execute position
ls -ld /tmp
# drwxrwxrwt 12 root root ...
#        ^ = sticky bit
 
# Set sticky bit
chmod o+t shared_directory/
ls -ld shared_directory/
# drwxrwxrwt 1 john users ...
 
# Octal notation (1000)
chmod 1777 shared_directory/
 
# Effect of sticky bit
# Owner of file can delete: YES
# Owner of directory can delete: YES (regardless of file owner)
# Other users can delete: NO (even with write permission)
 
# Create test scenario
mkdir /tmp/test_sticky
chmod 777 /tmp/test_sticky
 
# User 1 creates file
touch /tmp/test_sticky/file_from_user1.txt
 
# User 2 tries to delete
rm /tmp/test_sticky/file_from_user1.txt
# rm: cannot remove '/tmp/test_sticky/file_from_user1.txt': Operation not permitted
 
# Remove sticky bit
chmod o-t shared_directory/

Combined Special Permissions

# SUID + SGID + sticky bit
chmod 7755 file.sh
# 7 = 4 (SUID) + 2 (SGID) + 1 (sticky)
# 755 = rwxr-xr-x
 
ls -l file.sh
# -rwsr-sr-t 1 john users ...
 
# More practical combinations
chmod 4755 /usr/bin/sudo         # SUID only
chmod 2755 /usr/local/bin/group  # SGID only
chmod 1777 /tmp                  # Sticky bit only

ACLs (Access Control Lists)

Advanced permissions allowing fine-grained access control.

Getting and Setting ACLs

# Install acl package if needed
sudo apt-get install acl
 
# View ACLs
getfacl file.txt
# file: file.txt
# owner: john
# group: users
# user::rw-
# group::r--
# other::r--
 
# View ACLs for directory
getfacl -R /home/john/projects/ | head -20
 
# Set ACL for specific user
setfacl -m u:sarah:rwx file.txt
getfacl file.txt
 
# Set ACL for specific group
setfacl -m g:developers:rx script.sh
getfacl script.sh
 
# Set default ACL for new files in directory
setfacl -d -m u:sarah:rwx /home/john/projects/
# All new files in this directory will have ACL for sarah
 
# Remove ACL
setfacl -x u:sarah file.txt
setfacl -x g:developers script.sh
 
# Remove all ACLs except base
setfacl -b file.txt
 
# Copy ACLs from one file to another
getfacl source.txt | setfacl -f - target.txt

Practical ACL Examples

# Example 1: Allow developer group to modify code
setfacl -R -m g:developers:rwx /var/www/app/
getfacl /var/www/app/index.php
 
# Example 2: Set default ACL for team project
mkdir /home/projects/team-a
setfacl -d -m u::rwx /home/projects/team-a/
setfacl -d -m g:team-a:rwx /home/projects/team-a/
setfacl -d -m o::--- /home/projects/team-a/
 
# Example 3: Grant temporary access
setfacl -m u:contractor:r /home/john/document.pdf
# ... do work ...
setfacl -x u:contractor /home/john/document.pdf
 
# Example 4: Complex permission structure
setfacl -m u:john:rwx /home/shared/
setfacl -m u:sarah:rx /home/shared/
setfacl -m g:admin:rwx /home/shared/
setfacl -m o::--- /home/shared/
getfacl /home/shared/

Practical Permission Scenarios

Web Application Permissions

# Web server needs to read and write uploads
sudo chown www-data:www-data /var/www/app/uploads/
sudo chmod 775 /var/www/app/uploads/
 
# Config files (read only for web server)
sudo chown root:root /var/www/app/config.php
sudo chmod 640 /var/www/app/config.php
sudo chgrp www-data /var/www/app/config.php
 
# Private keys (read only for owner)
sudo chmod 600 /home/john/.ssh/id_rsa
 
# SSH configuration (owner read/write only)
sudo chmod 700 /home/john/.ssh/
sudo chmod 600 /home/john/.ssh/config

Secure Data Storage

# Create private directory
mkdir ~/private
chmod 700 ~/private
 
# Add sensitive file
echo "password" > ~/private/secrets.txt
chmod 600 ~/private/secrets.txt
 
# Check permissions
ls -la ~/private/
# total 8
# drwx------ 1 john users 4096 Jan 23
# -rw------- 1 john users    8 Jan 23 secrets.txt
 
# Only the owner can access
cat ~/private/secrets.txt  # Works
sudo cat ~/private/secrets.txt  # Fails
 
# Give another user read-only access (via ACL)
setfacl -m u:sarah:r ~/private/secrets.txt

Team Collaboration

# Create shared project directory
mkdir /opt/project
sudo chown john:developers /opt/project
sudo chmod 2775 /opt/project
 
# All team members can work here
touch /opt/project/file.txt
# File is automatically owned by 'developers' group
 
# Add new member to group
sudo usermod -aG developers newmember
 
# Verify group membership
groups newmember
# newmember : newmember developers

Finding Files by Permissions

# Find all SUID files
sudo find / -perm -4000 2>/dev/null
 
# Find all SGID files
sudo find / -perm -2000 2>/dev/null
 
# Find all files with sticky bit
sudo find / -perm -1000 2>/dev/null
 
# Find world-writable files (security risk)
sudo find / -perm -002 2>/dev/null
 
# Find files with no extension and execute bit
find /home -type f ! -name "*.*" -perm /111
 
# Find files with specific permissions (exactly 644)
find /home -type f -perm 644
 
# Find readable files for everyone
find /home -perm -444 -type f

Best Practices

  1. Use Principle of Least Privilege - Grant only necessary permissions
  2. Regularly Audit Permissions - Check for overly permissive files
  3. Avoid World-Writable Files - Use 644 for files, 755 for directories
  4. Secure Private Keys - Always use 600 permissions (rw-------)
  5. Be Careful with SUID/SGID - Only use when absolutely necessary
  6. Document Permission Changes - Keep notes on why permissions were changed
  7. Test After Changes - Verify applications work with new permissions
  8. Use ACLs for Complex Needs - For finer control than standard permissions

Summary

File permissions are critical for system security and functionality:

  • chmod changes file/directory permissions using symbolic or octal notation
  • chown changes file ownership
  • chgrp changes group ownership
  • umask sets default permissions for new files
  • SUID, SGID, and sticky bit provide special permissions for specific use cases
  • ACLs enable fine-grained access control
  • Proper permission management protects data and maintains system security

Understanding these tools enables you to create secure, functional Linux systems.