Linux File Permissions Explained
A visual guide to understanding how Linux decides who can read, write, and execute every file on your system -- and why it matters for security.
What Are File Permissions and Why They Matter
Every file and directory on a Linux system has a set of permissions that determine who can access it and what they can do with it. Permissions are the foundation of Linux security: they prevent unauthorized users from reading sensitive configuration, stop accidental deletion of critical system files, and ensure that only approved programs can be executed.
When a web application is compromised, proper file permissions are often the last line of defense preventing an attacker from modifying server configurations, reading database credentials, or installing malicious software. Understanding permissions is not optional for anyone managing a Linux server -- it is fundamental.
Reading ls -l Output
The ls -l command shows the long listing format, which displays permissions alongside other metadata. Here is what each field means:
-rwxr-xr-x -- File type + permissions1 -- Number of hard linksalice -- Owner usernamedevelopers -- Group name4096 -- File size in bytesJan 15 10:30 -- Last modifiedThe first character indicates the file type: - for a regular file, d for a directory, l for a symbolic link, and several other types for special files. The next nine characters are the permission string, divided into three triads of three characters.
The Permission Model: User, Group, Others
Linux evaluates permissions against three categories. Every process (running program) on the system has an associated user ID and group membership list. When that process tries to access a file, the kernel checks which category the process falls into:
- User (owner) -- If the process is running as the file's owner, the first triad of permissions applies. This is the most privileged position.
- Group -- If the process is not the owner but belongs to the file's group, the second triad applies. Groups are how Linux implements shared access between specific users without opening access to everyone.
- Others -- If the process is neither the owner nor in the group, the third triad applies. This represents all other users on the system.
Each triad contains three permission bits: read (r), write (w), and execute (x). A letter means the permission is granted; a dash means it is denied.
What Each Permission Means: Files vs Directories
The same permission bits have different practical effects depending on whether they are applied to a file or a directory. This distinction is one of the most commonly misunderstood aspects of Linux permissions:
| Permission | On a File | On a Directory |
|---|---|---|
| r (read) | View the file contents (e.g., cat, less) | List the directory entries (e.g., ls) |
| w (write) | Modify the file contents or truncate it | Create, delete, or rename files inside the directory |
| x (execute) | Run the file as a program or script | Enter the directory (cd) and access files by name |
A subtle but critical detail: on a directory, the execute bit controls whether you can traverse into the directory, not whether you can list its contents. You can have execute without read (meaning you can cd into the directory and access files by name, but you cannot list what is inside). This is sometimes used to create "secret" shared directories where you must know the filename to access it.
How Linux Decides Access
When a process attempts to access a file, the kernel follows a specific decision tree. Understanding this order is essential for debugging permission issues:
- Root check: If the process is running as root (UID 0), most permission checks are bypassed entirely. Root can read and write almost anything. (There are exceptions involving certain filesystem features and SELinux/AppArmor.)
- Owner check: If the effective user ID of the process matches the file's owner, only the owner permissions (first triad) are checked. Group and others permissions are completely ignored.
- Group check: If the process's effective group ID or supplementary groups include the file's group, only the group permissions (second triad) are checked.
- Others check: If neither the owner nor group matches, the others permissions (third triad) are checked.
An important consequence: if you are the file owner, only the owner permissions apply. Even if the group or others permissions are more permissive, they do not help you. This means a file with permissions 044 denies the owner all access while allowing the group and others to read.
Default Permissions and umask
When a new file or directory is created, it does not automatically get 777 permissions. Instead, Linux starts with a base permission value and subtracts the current umask. The base permissions are 666 for files (no execute by default) and 777 for directories (execute is needed for traversal).
The most common umask is 022, which results in files being created with 644 and directories with 755. This is a sensible default: the owner has full control, while group and others get read-only access. For a deeper dive into umask mechanics and configuration, see our umask guide.
Common Real-World Scenarios
Web Server Files
A typical web server setup uses 644 for static files (HTML, CSS, images) and 755 for directories. PHP or CGI scripts that need to be executed by the web server process typically need 755. Configuration files containing database passwords should be 600 or 640, readable only by the owner or a specific group.
SSH Keys
SSH is extremely strict about permissions. Your private key (~/.ssh/id_rsa) must be 600 or 400. The ~/.ssh directory itself must be 700. The authorized_keys file must be 600. If any of these are too permissive, SSH will refuse to use them and display a warning about "unprotected private key file."
Shared Directories
For team collaboration, you might set a shared directory to 2775 -- the setgid bit (2) ensures new files inherit the directory's group, while 775 gives the owner and group full access with read and execute for others. This is the standard pattern for shared project directories.
Dangerous Permission Patterns
Certain permission configurations are red flags that indicate potential security vulnerabilities:
- World-writable files (xx7 or xx6): Any file or directory where the others permission includes write is a security risk. World-writable directories allow any user to create, modify, or delete files. Directories like
/tmpmitigate this with the sticky bit, but world-writable files in application directories are almost always a mistake. - SUID on shell scripts: Setting the setuid bit on a shell script is extremely dangerous and most modern Linux systems ignore it for scripts. An attacker could manipulate environment variables or race conditions to execute arbitrary commands with elevated privileges.
- 777 on anything in production: Full permissions for everyone means any compromised process or malicious user can read, modify, or execute the file. This is the most common permission mistake made by developers frustrated by "permission denied" errors.
- Writable configuration files: If an attacker can write to configuration files like
/etc/crontab,.bashrc, or application config, they can achieve persistent access or privilege escalation.
Try It Yourself
The best way to internalize file permissions is to experiment. Use our chmod calculator to toggle permission bits and watch how the numeric and symbolic representations change. Try setting the permissions from the scenarios above and observe the corresponding chmod command that gets generated.
Further Reading
- POSIX file permission specification
The Open Group specification for file mode bits and permission flags.
- stat(2) — Linux man page
Linux system call documentation for reading file permission information.
- Arch Wiki — File permissions
Practical guide to Unix file permissions, ownership, and special bits.