funwithlinux guide

Understanding Linux File Permissions: A Comprehensive Guide

Linux, being a multi-user operating system, relies on a robust permission system to ensure security, privacy, and order. Every file and directory on a Linux system has associated permissions that dictate who can access it and what actions they can perform (e.g., read, write, execute). Whether you’re a system administrator, developer, or casual user, understanding Linux file permissions is critical for managing access, troubleshooting errors like "Permission denied," and safeguarding sensitive data. This guide will break down everything you need to know about Linux file permissions, from basic concepts to advanced special permissions, with practical examples and best practices.

Table of Contents

  1. What Are Linux File Permissions?
  2. Permission Types: Read, Write, Execute
  3. Permission Representation: Symbolic vs. Numeric
  4. Viewing File Permissions with ls -l
  5. Changing Permissions with chmod
  6. Changing Ownership with chown and chgrp
  7. Special Permissions: SUID, SGID, and Sticky Bit
  8. Default Permissions and umask
  9. Common Scenarios and Troubleshooting
  10. Best Practices for File Permissions
  11. Conclusion
  12. References

What Are Linux File Permissions?

File permissions in Linux are rules that control access to files and directories. They determine:

  • Who can access the file (user categories: owner, group, others).
  • What actions can be performed (read, write, execute).

Linux categorizes users into three groups for permission purposes:

  • Owner: The user who created the file (or was assigned ownership).
  • Group: A collection of users with shared access (e.g., a team working on a project).
  • Others: All users not in the owner or group categories (the “public”).

Permissions are defined separately for each group, ensuring granular control over access.

Permission Types: Read, Write, Execute

There are three core permission types, each with distinct behavior for files and directories:

1. Read (r)

  • Files: Allows viewing the file’s content (e.g., cat file.txt, less file.txt).
  • Directories: Allows listing the directory’s contents (e.g., ls dir/).

2. Write (w)

  • Files: Allows modifying, renaming, or deleting the file (e.g., nano file.txt, rm file.txt).
  • Directories: Allows adding, removing, or renaming files/directories within it (even if you don’t own those files).

3. Execute (x)

  • Files: Allows running the file as a program or script (e.g., ./script.sh, python script.py).
  • Directories: Allows accessing the directory (e.g., cd dir/) and executing files within it (requires execute permission on the directory and the file).

Key Note: For directories, the execute permission is critical—without it, you cannot access the directory, even if you have read permission.

Permission Representation: Symbolic vs. Numeric

Linux permissions are represented in two formats: symbolic (human-readable) and numeric (octal, for command-line use).

Symbolic Representation

Symbolic permissions use a 10-character string (e.g., -rwxr-xr--), where:

  • The first character indicates the file type:
    • -: Regular file
    • d: Directory
    • l: Symbolic link
    • b: Block device (e.g., hard drive)
    • c: Character device (e.g., keyboard)
  • The next 9 characters are split into 3 groups of 3, representing permissions for:
    • Owner (u): Characters 2–4
    • Group (g): Characters 5–7
    • Others (o): Characters 8–10

Each group uses r (read), w (write), x (execute), or - (no permission).

Example: -rwxr-xr--

  • File type: Regular file (-).
  • Owner: rwx (read, write, execute).
  • Group: r-x (read, execute).
  • Others: r-- (read only).

Numeric (Octal) Representation

Numeric permissions use a 3- or 4-digit octal (base-8) number, where each digit corresponds to the sum of permissions for a user group. The values are:

  • 4: Read (r)
  • 2: Write (w)
  • 1: Execute (x)

Permissions for a group are calculated by summing these values:

PermissionNumeric ValueSymbol
Read4r
Write2w
Execute1x
Read + Write6rw-
Read + Execute5r-x
Write + Execute3-wx
Read + Write + Execute7rwx

Example: rwxr-xr-- translates to:

  • Owner: rwx = 4+2+1 = 7
  • Group: r-x = 4+0+1 = 5
  • Others: r-- = 4+0+0 = 4
  • Numeric: 754

Viewing File Permissions with ls -l

To view permissions for files and directories, use the ls -l command (long format). The output includes permission details, ownership, size, and more.

Sample Output of ls -l:

-rwxr-xr-- 1 alice developers 1234 May 20 14:30 script.sh
drwxrwx--- 2 bob   team        4096 Jun 5  09:15 project/
lrwxrwxrwx 1 root  root          10 Apr 1  2023 link.txt -> file.txt

Breakdown of the Output:

ColumnDescription
1File type and permissions (e.g., -rwxr-xr-- for a regular file with rwxr-xr--).
2Number of hard links to the file/directory.
3Owner of the file/directory (e.g., alice).
4Group associated with the file/directory (e.g., developers).
5Size in bytes (e.g., 1234).
6-7Last modified date and time (e.g., May 20 14:30).
8File/directory name (e.g., script.sh).

Changing Permissions with chmod

The chmod (change mode) command modifies file/directory permissions. It supports both symbolic and numeric syntax.

Symbolic Syntax

Use the format:

chmod [who][operator][permissions] file/dir
  • who: Target user group(s):
    • u: Owner (user)
    • g: Group
    • o: Others
    • a: All (owner + group + others)
  • operator:
    • +: Add permission
    • -: Remove permission
    • =: Set exact permission (overrides existing)
  • permissions: r, w, x

Examples:

  • Add execute permission for the owner:

    chmod u+x script.sh  # Result: -rwxr-xr-- → -rwxr-xr-- (owner gains x)
  • Remove write permission for the group:

    chmod g-w project/  # Result: drwxrwx--- → drwxr-x--- (group loses w)
  • Set read/write for owner, read-only for group/others:

    chmod u=rw,go=r file.txt  # Result: -rw-r--r--
  • Add read/execute for all:

    chmod a+rx docs/  # Result: drwx------ → drwxr-xr-x

Numeric Syntax

Use the format:

chmod [numeric] file/dir

The numeric value is a 3- or 4-digit octal (e.g., 755, 600).

Examples:

  • Set rwxr-xr-x (owner: full access, group/others: read/execute):

    chmod 755 app/  # Common for executable directories/scripts
  • Set rw------- (owner: read/write, group/others: no access):

    chmod 600 private.key  # Secure for sensitive files (e.g., SSH keys)
  • Set rwxrwxrwx (world-writable, avoid this!):

    chmod 777 temp/  # Risks: anyone can modify/delete files

Changing Ownership with chown and chgrp

Permissions depend on ownership. Use chown (change owner) and chgrp (change group) to modify ownership.

chown: Change Owner (and Group)

Syntax:

chown [new-owner][:new-group] file/dir
  • Only the root user can change ownership of files/directories.

Examples:

  • Change owner to bob:

    sudo chown bob file.txt
  • Change owner to alice and group to team:

    sudo chown alice:team project/

chgrp: Change Group

Syntax:

chgrp new-group file/dir
  • Users can change the group of their own files to any group they belong to.

Example:

Change group to developers:

chgrp developers code/  # Requires user to be in "developers" group

Special Permissions: SUID, SGID, and Sticky Bit

Beyond rwx, Linux supports three special permissions for advanced use cases:

1. SUID (Set User ID)

  • Symbol: s (replaces x in the owner’s permission group, e.g., rwsr-xr-x).
  • Behavior: When a file with SUID is executed, it runs with the owner’s permissions (not the executor’s).
  • Use Case: Programs needing elevated privileges (e.g., passwd, which modifies /etc/passwd).

Set SUID:

chmod u+s file  # Numeric: add 4 as the first digit (e.g., 4755)

Example:

ls -l /usr/bin/passwd
# Output: -rwsr-xr-x 1 root root 68208 Mar 15 2023 /usr/bin/passwd

2. SGID (Set Group ID)

  • Symbol: s (replaces x in the group’s permission group, e.g., rwxr-sr-x).
  • Behavior:
    • Files: Runs with the group’s permissions.
    • Directories: New files/directories inherit the directory’s group (instead of the creator’s primary group).
  • Use Case: Shared directories (e.g., a team folder where all files belong to the team group).

Set SGID:

chmod g+s dir/  # Numeric: add 2 as the first digit (e.g., 2775)

Example:

chmod 2775 shared/  # New files in shared/ inherit the "shared" group

3. Sticky Bit

  • Symbol: t (replaces x in the others’ permission group, e.g., rwxrwxrwt).
  • Behavior: On directories, only the owner of a file (or root) can delete/rename it—even if others have write permission.
  • Use Case: Public directories like /tmp (prevents users from deleting each other’s files).

Set Sticky Bit:

chmod o+t dir/  # Numeric: add 1 as the first digit (e.g., 1777)

Example:

ls -ld /tmp
# Output: drwxrwxrwt 23 root root 4096 Jun 10 12:00 /tmp/

Default Permissions and umask

When you create a new file or directory, Linux assigns default permissions based on the umask (user file-creation mode mask).

How umask Works

  • Base Permissions:
    • Files: 666 (read/write for all).
    • Directories: 777 (read/write/execute for all).
  • umask: Subtracts permissions from the base. For example, a umask of 022 means:
    • New file: 666 - 022 = 644 (rw-r--r--).
    • New directory: 777 - 022 = 755 (rwxr-xr-x).

Viewing/Setting umask

  • Check current umask:

    umask  # Default: 0022 (root: 0077)
  • Set umask temporarily:

    umask 002  # New files: 664 (rw-rw-r--), directories: 775 (rwxrwxr-x)
  • Set umask permanently: Add umask 002 to ~/.bashrc (user-specific) or /etc/profile (system-wide).

Common Scenarios and Troubleshooting

”Permission Denied” Errors

  • Cause: Missing execute permission on a directory (can’t cd into it) or missing read/write/execute on a file.
  • Fix:
    # Allow cd into dir (add execute for user)
    chmod u+x dir/
    
    # Allow reading a file
    chmod o+r file.txt

Making a Script Executable

Scripts require execute permission to run with ./script.sh:

chmod +x script.sh  # Shorthand for chmod a+x script.sh

Securing Sensitive Files

Restrict access to SSH keys, passwords, or private data:

chmod 600 ~/.ssh/id_rsa  # Owner read/write only
chmod 700 ~/.ssh/        # Owner full access only

Shared Team Directory

Ensure all team members can read/write files in a shared directory:

chmod 775 shared/          # Group read/write/execute
chmod g+s shared/          # New files inherit the group
chown :team shared/        # Set group to "team"

Best Practices for File Permissions

  1. Principle of Least Privilege: Assign only the permissions needed (e.g., avoid 777).
  2. Avoid World-Writable Files: 777 permissions allow anyone to modify/delete files—use 775 (group-writable) instead.
  3. Restrict SUID/SGID: Only use SUID/SGID for critical programs (e.g., passwd); misuse risks privilege escalation.
  4. Audit Permissions: Use find to identify risky permissions:
    # Find world-writable files
    find / -perm -0002 -type f 2>/dev/null
    
    # Find SUID files
    find / -perm -4000 -type f 2>/dev/null
  5. Secure Sensitive Directories: Set 700 for ~/.ssh/, 600 for ~/.bash_history, etc.

Conclusion

Linux file permissions are a cornerstone of system security and access control. By mastering symbolic/numeric representation, chmod, chown, special permissions, and umask, you can ensure files are accessible to authorized users and protected from misuse. Always follow the principle of least privilege, audit permissions regularly, and avoid overly permissive settings like 777. With practice, managing permissions will become second nature!

References