Linux File Permissions: A Complete Guide
File permissions are one of the fundamental security features in Linux and Unix-like operating systems. They control who can read, write, or execute files and directories, forming the foundation of the multi-user security model that makes Linux systems secure and reliable.
In this guide, you'll learn how to view, understand, and modify file permissions, work with octal notation, handle special permissions, and troubleshoot common permission-related issues.
How to View File Permissions in Linux
The most common way to view file permissions is using the ls -l
command:
ls -l blog.marcnuri.com.txt
This produces output like:
-rw-r--r-- 1 marc users 1024 Oct 17 10:00 blog.marcnuri.com.txt
Let's break down what each part means:
-rw-r--r--
- The permission string (we'll decode this next)1
- Number of hard linksmarc
- Owner of the fileusers
- Group that owns the file1024
- File size in bytesOct 17 10:00
- Last modification date and timeblog.marcnuri.com.txt
- File name
For more detailed information, you can use the stat
command:
stat blog.marcnuri.com.txt
This shows additional metadata including access and modification times, inode number, and both symbolic and octal permission representations.
Understanding the Permission String
The permission string -rw-r--r--
contains 10 characters. Let's decode them position by position:
Position 1 - File type:
-
Regular filed
Directoryl
Symbolic linkc
Character deviceb
Block device
Positions 2-4 - Owner/user permissions:
r
Read permissionw
Write permissionx
Execute permission-
Permission not granted
Positions 5-7 - Group permissions (same format as owner)
Positions 8-10 - Other/world permissions (same format as owner)
So -rw-r--r--
means:
- It's a regular file (
-
) - Owner can read and write (
rw-
) - Group can only read (
r--
) - Others can only read (
r--
)
Permission Types Explained
The three basic permission types behave differently for files and directories:
Read Permission (r)
For files: Allows viewing the file's contents.
cat blog.marcnuri.com.txt
For directories: Allows listing the directory's contents.
ls /some/directory
Without read permission on a directory, you can't see what files it contains, even if you know their names.
Write Permission (w)
For files: Allows modifying the file's contents.
echo "new content" > blog.marcnuri.com.txt
For directories: Allows creating, deleting, or renaming files within the directory.
Note that to delete a file, you need write permission on the directory, not the file itself.
Execute Permission (x)
For files: Allows running the file as a program or script.
./script.sh
For directories: Allows accessing the directory (entering it with cd
) and accessing files within it.
This is crucial: even if a directory has read permission, you need execute permission to cd
into it or access files inside.
Permission Groups
Linux divides permissions into three groups:
Owner (User): The user who owns the file. Usually the person who created it, though ownership can be changed.
Group: A set of users who share access. Useful for team collaboration where multiple users need the same access level.
Others (World): Everyone else on the system who is not the owner or in the group.
This three-tier system provides flexible control over who can access your files while maintaining simplicity.
Octal Notation (Numeric Permissions)
Permissions can be represented as three-digit octal numbers, where each digit represents one permission group (owner, group, others).
Each permission type has a numeric value:
- Read (r) = 4
- Write (w) = 2
- Execute (x) = 1
- No permission = 0
You add these values together for each group:
Symbolic | Binary | Octal | Meaning |
---|---|---|---|
--- | 000 | 0 | No permissions |
--x | 001 | 1 | Execute only |
-w- | 010 | 2 | Write only |
-wx | 011 | 3 | Write and execute |
r-- | 100 | 4 | Read only |
r-x | 101 | 5 | Read and execute |
rw- | 110 | 6 | Read and write |
rwx | 111 | 7 | Read, write, and execute |
Common Permission Combinations
755 (rwxr-xr-x
) - Executable files and directories
- Owner can do anything
- Group and others can read and execute
- Common for scripts and programs
644 (rw-r--r--
) - Regular files
- Owner can read and write
- Group and others can only read
- Common for documents and configuration files
600 (rw-------
) - Private files
- Only owner can read and write
- Nobody else has any access
- Common for SSH keys and sensitive data
777 (rwxrwxrwx
) - Full access for everyone
- Everyone can do anything
- Generally considered insecure
- Avoid unless absolutely necessary
How to Change File Permissions (chmod)
The chmod
command changes file permissions. It supports two modes: symbolic and numeric.
Symbolic Mode
Symbolic mode uses letters and operators to modify permissions:
# Add execute permission for owner
chmod u+x script.sh
# Remove write permission for group
chmod g-w document.txt
# Set exact permissions for others (read only)
chmod o=r file.txt
# Add read and write for owner, remove execute for others
chmod u+rw,o-x file.txt
The format is: [who][operator][permissions]
Who:
u
- User/ownerg
- Groupo
- Othersa
- All (user, group, and others)
Operators:
+
- Add permission-
- Remove permission=
- Set exact permission
Numeric Mode
Numeric mode uses octal values to set permissions:
# Set permissions to rwxr-xr-x
chmod 755 script.sh
# Set permissions to rw-r--r--
chmod 644 document.txt
# Set permissions to rw-------
chmod 600 private-key.pem
Recursive Permissions
To change permissions for a directory and all its contents, use the -R
flag:
chmod -R 755 /path/to/directory
Be careful with recursive operations as they affect all files and subdirectories.
Directory vs File Permissions
Directories need different permission combinations than files to function properly.
For a directory to be usable, it typically needs execute permission. Without it, you cannot cd
into the directory or access files inside it, even if you have read permission.
Common scenarios:
# Directory with r-- (readable but not accessible)
ls /some/dir # Works - shows file names
cd /some/dir # Fails - cannot enter
cat /some/dir/file # Fails - cannot access files
# Directory with --x (accessible but not readable)
ls /some/dir # Fails - cannot list contents
cd /some/dir # Works - can enter
cat /some/dir/file # Works if you know the file name
For normal directory operation, you typically want both read and execute permissions (e.g., 755
or 750
).
Special Permissions
Beyond the basic permissions, Linux supports three special permission types:
SetUID (SUID)
When set on an executable file, the program runs with the permissions of the file's owner, not the user who executed it.
# Set SUID
chmod u+s /usr/bin/passwd
# Or using octal
chmod 4755 /usr/bin/passwd
The passwd
command uses SUID because it needs to modify /etc/shadow
(a root-owned file) even when run by regular users.
SUID appears as s
in the owner's execute position:
-rwsr-xr-x 1 root root 68208 Oct 17 10:00 /usr/bin/passwd
SetGID (SGID)
For files: The file runs with the permissions of the file's group.
For directories: Files created within the directory inherit the directory's group, not the creator's primary group.
# Set SGID
chmod g+s /shared/project
# Or using octal
chmod 2775 /shared/project
SGID appears as s
in the group's execute position:
drwxrwsr-x 2 marc developers 4096 Oct 17 10:00 /shared/project
Sticky Bit
When set on a directory, only the file's owner, the directory's owner, or root can delete or rename files within that directory.
# Set sticky bit
chmod +t /tmp
# Or using octal
chmod 1777 /tmp
The sticky bit appears as t
in the others' execute position:
drwxrwxrwt 2 root root 4096 Oct 17 10:00 /tmp
This is commonly used on /tmp
to prevent users from deleting each other's temporary files.
Combining Special Permissions
Special permissions add a fourth digit to octal notation:
chmod 4755 file # SUID + 755
chmod 2755 dir # SGID + 755
chmod 1777 dir # Sticky bit + 777
chmod 6755 file # SUID + SGID + 755
The special permissions digit values:
- 4 = SUID
- 2 = SGID
- 1 = Sticky bit
Changing Ownership (chown and chgrp)
To change who owns a file, use the chown
command:
# Change owner only
sudo chown marc file.txt
# Change owner and group
sudo chown marc:developers file.txt
# Change group only
sudo chown :developers file.txt
# Or use chgrp
sudo chgrp developers file.txt
# Recursive ownership change
sudo chown -R marc:developers /path/to/directory
Changing ownership typically requires root privileges (via sudo
) unless you own the file and are changing it to a group you belong to.
Default Permissions and umask
When you create a new file or directory, Linux applies default permissions based on the umask
value.
The umask is a mask that subtracts permissions from the base defaults:
- Base default for files:
666
(rw-rw-rw-) - Base default for directories:
777
(rwxrwxrwx)
The umask value is subtracted from these base permissions.
# View current umask
umask
# View in symbolic notation
umask -S
# Set umask
umask 0022
Common umask values:
0022 - Default on many systems
- Files created with
644
(rw-r--r--): 666 - 022 = 644 - Directories created with
755
(rwxr-xr-x): 777 - 022 = 755
0002 - Common for shared environments
- Files created with
664
(rw-rw-r--): 666 - 002 = 664 - Directories created with
775
(rwxrwxr-x): 777 - 002 = 775
0077 - Restrictive (private files)
- Files created with
600
(rw-------): 666 - 077 = 600 - Directories created with
700
(rwx------): 777 - 077 = 700
To make the umask permanent, add it to your shell's configuration file (~/.bashrc
or ~/.zshrc
).
Common Permission Scenarios
Making Scripts Executable
After creating a shell script, make it executable:
chmod +x script.sh
# Now you can run it
./script.sh
Securing SSH Keys
SSH private keys must have restricted permissions:
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh
SSH will refuse to use keys with overly permissive permissions.
Web Server Permissions
For web servers like Apache or Nginx:
# Directories
chmod 755 /var/www/html
# Static files (HTML, CSS, JS)
chmod 644 /var/www/html/*.html
# PHP files (if not executing as owner)
chmod 644 /var/www/html/*.php
# Uploads directory (writable by web server)
chmod 775 /var/www/html/uploads
Shared Team Directories
For team collaboration:
# Create shared directory with SGID
mkdir /shared/project
chmod 2775 /shared/project
chgrp developers /shared/project
Now all files created in /shared/project
will belong to the developers
group, and group members can modify them.
Troubleshooting Common Issues
"Permission denied" when running a script
Problem: bash: ./script.sh: Permission denied
Solution: Add execute permission:
chmod +x script.sh
Can't delete a file you own
Problem: rm: cannot remove 'file.txt': Permission denied
Cause: You need write permission on the parent directory, not the file.
Solution:
chmod +w /parent/directory
Or if the directory has the sticky bit set, you must be the file's owner or the directory's owner.
Can't access files in a readable directory
Problem: ls
works but cat file
fails
Cause: Directory lacks execute permission.
Solution:
chmod +x /path/to/directory
SSH refuses to use your key
Problem: Permissions 0644 for '/home/marc/.ssh/id_rsa' are too open
Cause: SSH keys must be private (readable only by owner).
Solution:
chmod 600 ~/.ssh/id_rsa
chmod 700 ~/.ssh
Conclusion
Linux file permissions provide a robust and flexible security system:
- Use
ls -l
to view permissions in symbolic format - Three permission types: read (r), write (w), execute (x)
- Three permission groups: owner (u), group (g), others (o)
- Permissions can be represented symbolically (
rwxr-xr-x
) or numerically (755
) - Use
chmod
to change permissions,chown
to change ownership - Special permissions (SUID, SGID, sticky bit) provide advanced control
- Directories need execute permission to be accessible
- The
umask
controls default permissions for new files
Best Practices
- Follow the principle of least privilege (grant only necessary permissions)
- Use
600
for private keys and sensitive files - Use
644
for regular files,755
for executables and directories - Avoid
777
unless absolutely necessary - Use SGID for shared team directories
- Regularly audit permissions on sensitive files
Understanding file permissions is essential for Linux system administration, security, and effective collaboration in multi-user environments.