Linux File Permissions: rwx, chmod/chown, umask, SUID/SGID/Sticky, and Troubleshooting
Chen Kai BOSS

File permissions are "basic" in Linux, but they are also one of the most common causes of production incidents: a service won't start, a deploy script can't execute, a web app returns 403, or a shared directory becomes a security hole because permissions were made too broad. To use permissions correctly, you need more than memorizing chmod 755— you need to understand how permission bits have completely different semantics on files vs directories (r/w/x mean different things for directories), the boundaries between owner/group/others, and why mechanisms like umask, SUID/SGID, and the sticky bit exist and when they should be used. This post starts from the minimal concept set, systematically explains rwx semantics, numeric/symbolic notation, typical usage and troubleshooting approaches for chmod/chown, uses common scenarios (shared directories, executable scripts, temp directories, security hardening) to explain "how to grant permissions and to what extent," then adds extended mechanisms like ACL and chattr plus a practical troubleshooting checklist, enabling you to locate and correctly fix permission issues in one shot.

Linux Permission Model: The Three-Tier Architecture of owner/group/others

Basic Concepts

Linux is a multi-user system; every file/directory has three identity attributes:

  • Owner (u): The user (UID) who created or was designated as the file/directory owner
  • Group (g): Multiple users can belong to one group, sharing permissions within the group (GID)
  • Others (o): Everyone who is neither the file owner nor in the file's group

Why this design?

  • Owner: The file's "owner," usually has highest permissions (like read/write/execute)
  • Group: Suitable for team collaboration (like dev team, ops team), members share permissions
  • Others: Prevents files from being accessed by arbitrary users (security isolation)

Three Permission Bits (rwx)

Each identity (u/g/o) has three permission bits:

  • r (read): Read permission
  • w (write): Write permission
  • x (execute): Execute permission

Example: rwxr-xr-x

  • Owner: rwx (can read, write, execute)
  • Group: r-x (can read, execute, cannot write)
  • Others: r-x (can read, execute, cannot write)

Convert to numeric:

  • rwx = 4+2+1 = 7
  • r-x = 4+0+1 = 5
  • r-x = 4+0+1 = 5
  • So rwxr-xr-x = 755

rwx Semantic Differences on Files vs Directories (The Most Common Pitfall)

This is the most confusing point: rwx mean completely different things on files vs directories.

On Files (Regular Files)

Permission Meaning Example
r Can read file contents cat file.txt
w Can modify file contents echo "new" > file.txt
x Can execute file (scripts need shebang like #!/bin/bash) ./script.sh

On Directories

Permission Meaning Example
r Can list directory contents (see filenames) ls dir
w Can create, delete, rename files within directory (usually requires x) touch dir/newfile
x Can enter directory (cd), access files within if you know the name cd dir or cat dir/file.txt

Real-world examples:

Case 1: Directory has r but not x

1
2
3
4
chmod 644 mydir  # mydir permissions become rw-r--r-- (no x)
ls mydir # ✅ Can list filenames
cd mydir # ❌ Permission denied (can't enter)
cat mydir/file.txt # ❌ Permission denied (can't access file)

Reason: Without x, can't enter directory or access files within.

Case 2: Directory has x but not r

1
2
3
4
chmod 311 mydir  # mydir permissions become -wx--x--x (has x but not r)
ls mydir # ❌ Permission denied (can't list filenames)
cd mydir # ✅ Can enter
cat mydir/file.txt # ✅ Can access (if you know the filename)

Reason: With x you can enter and access files, but without r you can't list directory contents.

Case 3: Directory has w but not x

1
2
chmod 622 mydir  # mydir permissions become rw--w--w- (has w but not x)
touch mydir/newfile # ❌ Permission denied (can't create file)

Reason: Although it has w, without x you can't enter directory, so can't operate within.

Conclusion: For directories, x is the most fundamental permission (without x you can't do anything); w usually needs to be used with x.


chmod: Modifying Permissions (Numeric and Symbolic Notation)

Numeric Notation (Fast and Common)

Each permission bit corresponds to a number:

  • r = 4
  • w = 2
  • x = 1

Sum to get a 3-digit number (owner/group/others):

  • 7 = rwx (4+2+1)
  • 6 = rw- (4+2)
  • 5 = r-x (4+1)
  • 4 = r-- (4)
  • 0 = --- (no permissions)

Common examples:

1
2
3
4
chmod 755 script.sh  # owner=rwx, group=r-x, others=r-x (executable script)
chmod 644 file.txt # owner=rw-, group=r--, others=r-- (regular file)
chmod 600 secret.key # owner=rw-, group=---, others=--- (private key file)
chmod 777 shared # owner=rwx, group=rwx, others=rwx (fully open, not recommended)

Symbolic Notation (Safer, Suitable for Incremental Changes)

1
2
3
4
5
chmod u+x script.sh  # Add execute permission for owner
chmod g-w file.txt # Remove write permission for group
chmod o=r file.txt # Set others to only read permission
chmod a+r notes.md # Add read permission for all (a=all)
chmod u+rwx,g+rx,o-rwx dir # Combined modification (comma-separated)

Recursive modification:

1
2
chmod -R 755 dir  # Recursively modify directory and its contents
chmod -R u+rwX,g+rX,o-rwx dir # Capital X only adds x to directories and files that already have execute (avoids making all files executable)

When to use numeric vs symbolic?

  • Numeric: Suitable for "one-shot set to target value" (like chmod 644 file)
  • Symbolic: Suitable for "incremental modification" (like chmod u+x script.sh), safer (won't accidentally change other permission bits)

chown: Modifying File Ownership

chown is used to modify file owner and group.

Basic usage:

1
2
3
4
sudo chown newowner file  # Only change owner
sudo chown newowner:newgroup file # Change both owner and group
sudo chown :newgroup file # Only change group
sudo chown -R user:group dir # Recursively modify directory and its contents

Notes:

  • Only root or the file's current owner can modify ownership
  • Regular users can't "give" files to others (prevents malicious quota abuse)

Common scenarios:

  • Web server directory: sudo chown -R www-data:www-data /var/www/html
  • Shared project directory: sudo chown -R :developers /srv/project

umask: Default Permissions for New Files

What is umask

umask is the User File Creation Mask, determining default permissions for newly created files/directories.

Calculation method: 1. Default permissions (system preset):

  • Files: 666 (rw-rw-rw-, no execute permission, prevents accidental execution)
  • Directories: 777 (rwxrwxrwx, directories need x to be enterable)
  1. Actual permissions = Default permissions - umask value

Example (umask = 022):

  • File: 666 - 022 = 644 (rw-r--r--)
  • Directory: 777 - 022 = 755 (rwxr-xr-x)

View and Set umask

View current umask:

1
umask  # Output: 0022 (first digit is special permission bit, usually ignored)

Temporarily set umask:

1
2
umask 027  # Set to 027
# New files will have 640 (666-027), directories 750 (777-027)

Permanently set umask (for current user): Edit ~/.bashrc or ~/.zshrc, add:

1
umask 027

Common umask values:

umask File Perms Dir Perms Use Case
022 644 755 Default (files not modifiable by others)
027 640 750 Stricter (only group can access), recommended for production
002 664 775 Shared environment (group can modify), development
077 600 700 Extremely strict (only owner can access), personal private files

Special Permissions: SUID/SGID/Sticky Bit

These three special permission bits are for specific operational needs; understanding their principles and use cases is important.

SUID (Set User ID)

Principle

When an executable file is given SUID permission, ordinary users executing the file run it with the file owner's identity, not the caller's own identity.

Common example: /usr/bin/passwd

  • ls -l /usr/bin/passwd shows: -rwsr-xr-x root root (note owner's x became s)
  • When ordinary users execute passwd, it runs as root, allowing modification of /etc/shadow (only root can write)

Why is SUID needed?

  • Allows ordinary users to execute specific operations requiring high permissions (like changing own password)
  • Doesn't need to give users sudo privileges (more secure)

View and Set

View:

1
ls -l file  # If owner's x position shows s (lowercase) or S (uppercase), SUID is set

  • s (lowercase): SUID and has execute permission
  • S (uppercase): SUID but no execute permission (usually a configuration error)

Set SUID:

1
2
chmod u+s myprog  # Symbolic notation
chmod 4755 myprog # Numeric notation (4 means SUID, 755 is base permissions)

Remove SUID:

1
chmod u-s myprog

Hands-On Example

Suppose you have a C program myprog.c:

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
printf("Real UID=%d, Effective UID=%d\n", getuid(), geteuid());
system("id");
return 0;
}

Compile and set SUID:

1
2
3
gcc -o myprog myprog.c
sudo chown root myprog # Change owner to root
sudo chmod 4755 myprog # Set SUID + 755

Execute as ordinary user:

1
./myprog

Example output:

1
2
Real UID=1000, Effective UID=0
uid=1000(user) gid=1000(user) euid=0(root) groups=1000(user)

  • Real UID is current user (1000)
  • Effective UID is file owner (0=root)
  • So program runs with root privileges

Security Considerations

SUID is high-risk:

  • If SUID program has vulnerabilities (like buffer overflow, command injection), attackers can gain root privileges
  • Avoid setting SUID on untrusted programs
  • Regularly audit SUID programs on system

Find all SUID programs on system:

1
find / -perm -4000 -type f 2>/dev/null

Common SUID programs (these are reasonable):

  • /usr/bin/passwd: Change password
  • /usr/bin/sudo: Temporary privilege escalation
  • /usr/bin/mount: Mount filesystems
  • /usr/bin/ping: Send ICMP packets (needs raw socket permission)

SGID (Set Group ID)

Use Cases

SGID has two uses:

1. On Executable Files

When process runs, its effective group ID (GID) is replaced by the file's group. Common in tools that need to access specific group resources.

2. On Directories (More Common)

When a directory has SGID set, new files or subdirectories created within inherit the directory's group, not the creator's default group. This is perfect for team shared directories.

Example:

1
2
3
sudo mkdir /srv/project
sudo chown :developers /srv/project # Change group to developers
sudo chmod 2775 /srv/project # Set SGID + 775 (2 means SGID)

Now, any files created by developers group members in /srv/project automatically have group developers, accessible to other group members.

View and Set

View:

1
ls -l file  # If group's x position shows s (lowercase) or S (uppercase), SGID is set

Set SGID:

1
2
chmod g+s shared_dir  # Symbolic notation
chmod 2775 shared_dir # Numeric notation (2 means SGID)

Remove SGID:

1
chmod g-s shared_dir


Sticky Bit

Function and Principle

Sticky Bit is most common on multi-user writable public directories like /tmp. When a directory has Sticky Bit set, files in that directory can only be deleted or renamed by their owner or root, even if others have write permission on the directory.

Why is Sticky Bit needed?

  • /tmp is a temporary directory shared by all users, permissions are 1777 (rwxrwxrwt)
  • Without Sticky Bit, user A could delete user B's temp files (security risk)
  • With Sticky Bit, user A can only delete their own files, not user B's files

View and Set

View:

1
ls -ld /tmp  # Output: drwxrwxrwt (last character is t)

Set Sticky Bit:

1
2
chmod o+t dirname  # Symbolic notation
chmod 1777 /tmp # Numeric notation (1 means Sticky Bit)

Remove Sticky Bit:

1
chmod o-t dirname


Common Scenarios and Best Practices

Scenario 1: Executable Script

Problem: ./script.sh: Permission denied

Troubleshoot:

1
ls -l script.sh  # Check permissions

If it shows -rw-r--r-- (no x), execute permission is missing.

Solution:

1
2
3
chmod +x script.sh  # Add execute permission for all
# Or
chmod 755 script.sh # owner=rwx, group=r-x, others=r-x

Note: Script also needs shebang (like #!/bin/bash), otherwise need to run with bash script.sh.

Scenario 2: Web Server Directory

Requirement: Nginx/Apache needs to read files in /var/www/html.

Troubleshoot:

1
2
ls -ld /var/www /var/www/html
ls -l /var/www/html/index.html

Common issues:

  • Insufficient directory permissions (Nginx user doesn't have x permission, can't enter)
  • Insufficient file permissions (Nginx user doesn't have r permission, can't read)

Solution:

1
2
3
4
5
sudo chown -R www-data:www-data /var/www/html  # Change owner to www-data
sudo chmod -R 755 /var/www/html # Both directories and files set to 755
# Or stricter
sudo find /var/www/html -type d -exec chmod 755 {} \; # Directories 755
sudo find /var/www/html -type f -exec chmod 644 {} \; # Files 644

Scenario 3: Shared Directory (Team Collaboration)

Requirement: /srv/project directory, developers group members can all read/write, others cannot access.

Solution:

1
2
3
sudo mkdir /srv/project
sudo chown :developers /srv/project # Change group to developers
sudo chmod 2770 /srv/project # SGID + 770 (only owner and group can access)

  • 2: SGID (new files automatically inherit developers group)
  • 770: owner and group both rwx, others no permissions

Verification:

1
2
3
# User A (developers group member) creates file
touch /srv/project/fileA
ls -l /srv/project/fileA # Output: -rw-r--r-- userA developers

File group is automatically developers, other group members can also access.

Scenario 4: Temp Directory (Prevent Mutual File Deletion)

Requirement: /tmp directory, all users can create files, but can't delete others' files.

Solution:

1
sudo chmod 1777 /tmp  # Sticky Bit + 777

  • 1: Sticky Bit (only owner and root can delete files)
  • 777: All users can read/write/execute

Extended Mechanisms: ACL and chattr

ACL (Access Control Lists)

Why ACL is needed?

  • Traditional permissions can only set three layers (owner/group/others), not flexible enough
  • ACL can set permissions for specific users or specific groups (like "user A has read permission, user B has write permission")

View ACL:

1
getfacl file.txt

Set ACL:

1
2
3
4
setfacl -m u:alice:rw file.txt  # Give user alice read/write permission
setfacl -m g:dev:rx dir # Give group dev read/execute permission
setfacl -x u:alice file.txt # Remove alice's ACL
setfacl -b file.txt # Remove all ACLs

Recursive setting:

1
setfacl -R -m u:alice:rwx dir  # Recursively set

chattr: File Attributes (Prevent Accidental Deletion/Modification)

chattr can set special file attributes (supported by ext4 filesystem).

Common attributes:

  • i (immutable): File cannot be modified, deleted, renamed (not even by root, unless i attribute is removed first)
  • a (append-only): File can only be appended to, cannot modify existing content (suitable for log files)

Set immutable:

1
2
3
sudo chattr +i important.conf  # File becomes immutable
rm important.conf # ❌ Operation not permitted (not even root can delete)
sudo chattr -i important.conf # Remove i attribute before deleting

Set append-only:

1
2
3
sudo chattr +a logfile.txt  # Only append allowed
echo "new line" >> logfile.txt # ✅ Can append
echo "overwrite" > logfile.txt # ❌ Operation not permitted (cannot overwrite)

View attributes:

1
lsattr file.txt

Use cases:

  • Protect important config files (/etc/fstab, /etc/passwd)
  • Prevent log files from being cleared

Permission Troubleshooting Checklist: What to Do When Problems Arise

Problem 1: Permission denied

Troubleshooting steps: 1. Confirm executing user: whoami (or check service's running user, like systemd unit file) 2. View file permissions: ls -l file 3. View all parent directory permissions: namei -l /full/path/to/file (needs util-linux package) 4. Check group membership: id (see which groups current user belongs to) 5. Check special attributes: lsattr file (whether has i or a attribute)

Common causes:

  • File doesn't have read/write/execute permission
  • Parent directory doesn't have x permission (can't enter)
  • User not in file's group

Solutions:

1
2
3
4
sudo chmod 644 file  # Give read permission
sudo chmod +x script.sh # Give execute permission
sudo chmod 755 /path/to/parent/dir # Give parent directory x permission
sudo chown user:group file # Modify ownership

Problem 2: Web Server 403 Forbidden

Cause: Nginx/Apache user (like www-data, nginx) doesn't have permission to read file.

Troubleshoot:

1
2
3
ps aux | grep nginx  # Check nginx running user
ls -l /var/www/html/index.html # Check file permissions
namei -l /var/www/html/index.html # Check all parent directory permissions

Solution:

1
2
3
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html # Directories 755
sudo find /var/www/html -type f -exec chmod 644 {} \; # Files 644

Problem 3: Script Execution Fails

Cause: Script doesn't have execute permission or shebang is wrong.

Troubleshoot:

1
2
ls -l script.sh  # Check permissions
head -1 script.sh # Check shebang

Solution:

1
2
chmod +x script.sh  # Add execute permission
# Ensure shebang is correct (like #!/bin/bash)

Problem 4: rm: cannot remove 'file': Operation not permitted

Cause: File might have i attribute (immutable).

Troubleshoot:

1
lsattr file

If output contains i (like ----i--------), file has immutable attribute.

Solution:

1
2
sudo chattr -i file  # Remove i attribute
rm file # Can delete now


Summary and Further Reading

This article covers the core content of Linux file permissions: 1. ✅ Linux permission model (owner/group/others, rwx semantics) 2. ✅ rwx differences on files vs directories (most common pitfall) 3. ✅ chmod and chown usage (numeric/symbolic notation) 4. ✅ umask principles and common values (default permissions for new files) 5. ✅ Special permissions (SUID/SGID/Sticky Bit principles and use cases) 6. ✅ Extended mechanisms (ACL, chattr) 7. ✅ Permission troubleshooting checklist (Permission denied, 403, script execution failure, etc.)

Further Reading:

  • man chmod: View detailed chmod manual
  • man chown: View detailed chown manual
  • man 5 acl: View detailed ACL explanation
  • SELinux / AppArmor: More advanced security models (Mandatory Access Control MAC)

Next Steps:

  • 《 Linux User Management 》: Learn how to manage users/groups, /etc/passwd, /etc/shadow, sudo configuration
  • 《 Linux Advanced File Operations 》: Learn pipes, redirection, stdin/stdout/stderr, xargs, tee

By this point, you should have upgraded from "can use chmod 755" to "understand permission semantics, can design shared directory permission schemes, can troubleshoot permission issues." File permissions are the cornerstone of Linux security; mastering them allows you to better protect systems and data.

  • Post title:Linux File Permissions: rwx, chmod/chown, umask, SUID/SGID/Sticky, and Troubleshooting
  • Post author:Chen Kai
  • Create time:2022-12-15 00:00:00
  • Post link:https://www.chenk.top/en/linux-file-permissions/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
 Comments