L6. File Permissions: chmod, chown and ACLs
Video generating
Check back soon for the video lesson on File Permissions: chmod, chown and ACLs
Linux file permissions control who can read, write, and execute every file and directory on the system. This lesson covers the permission model, numeric notation, chmod, chown, special permission bits (SUID/SGID/sticky), and access control lists for fine-grained control.
The Linux Permission Model
Every file and directory on a Linux system has three sets of permissions, assigned to three categories of users:
| Category | Description |
|---|---|
| Owner (u) | The user who owns the file |
| Group (g) | Members of the file's assigned group |
| Others (o) | Everyone else on the system |
| Permission | On a File | On a Directory |
|---|---|---|
| Read (r) | View file contents | List directory contents |
| Write (w) | Modify file contents | Create/delete files in the directory |
| Execute (x) | Run as a program | Enter the directory (cd into it) |
Reading Permission Output
ls -l /etc/passwdOutput:
-rw-r--r-- 1 root root 2847 Jun 20 10:00 /etc/passwdBreaking down -rw-r--r--:
<ul class="list-disc pl-6 mb-4 space-y-2">
<li class="text-slate-300"> rw- r-- r--</li>
</ul>
| | | |
| | | +-- Others: read only
| | +-- Group: read only
| +-- Owner: read + write
+-- File type (- = file, d = directory, l = symlink)This means root can read and write the file. Everyone else can only read it. No one can execute it (which makes sense: it is a text file, not a program).
Numeric (Octal) Notation
Each permission has a numeric value:
| Permission | Value |
|---|---|
| Read (r) | 4 |
| Write (w) | 2 |
| Execute (x) | 1 |
| None (-) | 0 |
| Notation | Meaning |
|---|---|
| 755 | Owner: rwx (7), Group: r-x (5), Others: r-x (5) |
| 644 | Owner: rw- (6), Group: r-- (4), Others: r-- (4) |
| 700 | Owner: rwx (7), Group: --- (0), Others: --- (0) |
| 600 | Owner: rw- (6), Group: --- (0), Others: --- (0) |
Common Permission Patterns
| Permission | Typical Use |
|---|---|
| 755 | Executable files, public directories |
| 644 | Regular files (configs, documents) |
| 700 | Private directories, scripts for one user |
| 600 | Private keys, sensitive config files |
| 400 | Read-only sensitive files (SSL certificates) |
chmod: Changing Permissions
# Numeric notation
chmod 755 script.sh # Owner: rwx, Group: r-x, Others: r-x
chmod 600 private-key.pem # Owner: rw-, no access for anyone else
chmod 644 config.yaml # Owner: rw-, Group: r--, Others: r--# Symbolic notation
chmod u+x script.sh # Add execute permission for the owner
chmod g-w report.txt # Remove write permission from the group
chmod o-rwx secret.txt # Remove all permissions for others
chmod a+r public.txt # Add read permission for all (a = all)
# Recursive: apply to a directory and all contents
chmod -R 750 /opt/application/
Security note: Be extremely cautious with chmod -R. Applying recursive permissions to the wrong directory can lock you out of the system or expose sensitive files.
chown: Changing Ownership
# Change the owner of a file
sudo chown idan report.txt# Change owner and group
sudo chown idan:security-team report.txt
# Change only the group
sudo chown :security-team report.txt
# Recursive ownership change
sudo chown -R www-data:www-data /var/www/html/
Ownership determines which "owner" permissions apply to which user. Changing ownership is a root-level operation because allowing regular users to reassign file ownership would undermine the entire permission model.
Special Permission Bits
Beyond the standard read/write/execute, Linux has three special permission bits that have significant security implications.
SUID (Set User ID)
When the SUID bit is set on an executable, it runs with the permissions of the file owner, not the user who executed it.
# The passwd command has SUID set (note the 's' in owner execute position)
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 Jun 20 10:00 /usr/bin/passwdThis is how the passwd command lets a regular user change their own password: the program runs as root (the file owner) so it can write to /etc/shadow.
Security risk: SUID binaries are a common privilege escalation vector. If an attacker finds a SUID binary with a vulnerability, they can exploit it to gain root access.
# Find all SUID files on the system (important security audit command)
find / -perm -4000 -type f 2>/dev/null
SGID (Set Group ID)
When set on an executable, SGID runs the program with the group permissions of the file. When set on a directory, new files created inside inherit the directory's group instead of the creating user's primary group.
# Set SGID on a shared directory
chmod 2770 /opt/shared-reports/SGID on directories is useful for shared team folders where all files should belong to the team's group.
Sticky Bit
When set on a directory, the sticky bit prevents users from deleting files they do not own, even if they have write permission on the directory.
# /tmp has the sticky bit set (note the 't' at the end)
ls -ld /tmp
# drwxrwxrwt 15 root root 4096 Jun 20 10:00 /tmp# Set the sticky bit
chmod 1777 /tmp
Without the sticky bit, any user with write access to /tmp could delete other users' temporary files. The sticky bit ensures users can only delete their own files.
Access Control Lists (ACLs)
Standard Linux permissions only support one owner and one group per file. When you need more granularity, such as giving a specific user read access without changing the file's group, you use ACLs (Access Control Lists).
Checking ACL Support
# Most modern filesystems support ACLs. Check your mount options:
mount | grep acl
Setting ACLs
# Grant a specific user read access to a file
setfacl -m u:analyst:r-- /var/log/app/audit.log# Grant a specific group read and execute access to a directory
setfacl -m g:security-team:r-x /opt/tools/
# Set a default ACL (applies to new files created in the directory)
setfacl -d -m g:security-team:r-x /opt/tools/
# Remove an ACL entry
setfacl -x u:analyst /var/log/app/audit.log
# Remove all ACLs from a file
setfacl -b /var/log/app/audit.log
Viewing ACLs
# Check ACLs on a file
getfacl /var/log/app/audit.logOutput:
# file: var/log/app/audit.log
# owner: root
# group: adm
user::rw-
user:analyst:r--
group::r--
mask::r--
other::---A + sign at the end of ls -l output indicates that a file has ACLs set:
-rw-r-----+ 1 root adm 15234 Jun 20 10:00 audit.log
Security Auditing: What to Check
When hardening a Linux system or conducting a security assessment, check for these common permission issues:
# World-writable files (anyone can modify)
find / -perm -0002 -type f 2>/dev/null# SUID binaries (potential privilege escalation)
find / -perm -4000 -type f 2>/dev/null
# Files with no owner (orphaned, possibly from deleted users)
find / -nouser -o -nogroup 2>/dev/null
# Sensitive files with overly broad permissions
ls -l /etc/shadow # Should be 640 or more restrictive
ls -l ~/.ssh/id_rsa # Should be 600
ls -l /etc/ssh/sshd_config # Should be 644 or 600
These checks are part of every CIS Benchmark for Linux and should be automated in your hardening baseline.
- ✓Linux permissions are divided into owner, group, and others, each with read (4), write (2), and execute (1) values.
- ✓SUID binaries run with the file owner's permissions and are a common privilege escalation vector; audit them with find / -perm -4000.
- ✓The sticky bit on directories (like /tmp) prevents users from deleting files they do not own.
- ✓ACLs (setfacl/getfacl) provide fine-grained access beyond the standard owner/group/others model.
- ✓Critical files like /etc/shadow (640), SSH private keys (600), and sshd_config (644) must have restrictive permissions.
1. What does a permission of 600 mean in numeric notation?
2. Why are SUID binaries considered a security risk?
3. When would you use an ACL instead of standard Linux permissions?