Understanding Linux File Permissions
Master Linux file permissions from scratch: understand rwx bits, owner/group/other classes, chmod numeric and symbolic modes, chown, and the sticky bit.
Before you start
- ▸Access to a Linux terminal (local or SSH)
- ▸A non-root user account with sudo privileges
- ▸Basic familiarity with navigating the filesystem using cd and ls
Linux file permissions are the foundation of the operating system's security model. Every file and directory carries a set of permission bits that control exactly who can read it, write to it, or execute it. Once you understand the three-permission, three-class system, you'll be able to diagnose "permission denied" errors confidently and lock down files the right way.
How Permissions Are Structured
Run ls -l in any directory and you'll see output like this:
ls -l /etc/hosts
The output looks similar to:
-rw-r--r-- 1 root root 220 Apr 10 09:14 /etc/hosts
The first field, -rw-r--r--, is the permission string. Break it down character by character:
- Position 1 — file type:
-regular file,ddirectory,lsymlink,b/cblock/char device. - Positions 2–4 — owner (user) permissions:
rwx. - Positions 5–7 — group permissions:
rwx. - Positions 8–10 — other (everyone else) permissions:
rwx.
What r, w, and x Mean
| Bit | On a file | On a directory |
|---|---|---|
| r (read, 4) | Read file contents | List directory contents (ls) |
| w (write, 2) | Modify or truncate the file | Create, rename, or delete files inside |
| x (execute, 1) | Run the file as a program | Enter the directory (cd) and access its contents |
A - in any position means that permission is not granted.
The Three Permission Classes
Every file has an owning user and an owning group. When the kernel checks access it walks through the classes in order and stops at the first match:
- Owner (user) — the account that owns the file. Check with
stat filename. - Group — any user whose primary or supplementary group matches the file's group.
- Other — everyone else.
Importantly, if you are the owner, only the owner bits apply — the kernel never falls through to the group or other bits for you, even if those bits are more permissive.
Changing Permissions with chmod
chmod accepts two notation styles: numeric (octal) and symbolic. Both do the same job; use whichever is clearer for the task.
Numeric (Octal) Notation
Each permission class is represented by a single octal digit, which is the sum of its active bits: read (4) + write (2) + execute (1). You pass three digits: owner, group, other.
# Set owner=rwx, group=r-x, other=r-x (755 — typical for executables)
chmod 755 myscript.sh
# Set owner=rw-, group=r--, other=r-- (644 — typical for config files)
chmod 644 config.yaml
# Set owner=rw-, group=rw-, other=--- (660 — shared group file, no world access)
chmod 660 shared.db
A quick mental shortcut: 7 = full access, 6 = read+write, 5 = read+execute, 4 = read only, 0 = no access.
Symbolic Notation
Symbolic mode uses letters to identify who (u=user/owner, g=group, o=other, a=all three) and operators to add (+), remove (-), or set exactly (=) permissions.
# Add execute for the owner only
chmod u+x deploy.sh
# Remove write for group and other
chmod go-w secrets.conf
# Set group to exactly read+write, removing execute if set
chmod g=rw data.csv
# Add read for everyone
chmod a+r README.txt
Symbolic mode is safer for scripts because it makes relative changes rather than replacing all bits — you won't accidentally wipe a bit you didn't intend to touch.
Recursive Changes
Use -R to apply permissions recursively. Be careful: applying the same mode to both files and directories is usually wrong because directories need the execute bit to be traversable.
# Correct: set directories to 755 and files to 644 in one pass
find /var/www/html -type d -exec chmod 755 {} +
find /var/www/html -type f -exec chmod 644 {} +
Changing Ownership with chown
chown changes the owning user, the owning group, or both at once. You need sudo or root to change ownership to another user.
# Change owner to alice
sudo chown alice report.pdf
# Change owner to alice AND group to developers
sudo chown alice:developers report.pdf
# Change group only (colon with no user before it)
sudo chown :developers report.pdf
# Recursive ownership change
sudo chown -R www-data:www-data /var/www/html
To change only the group when you're the file owner and a member of the target group, use chgrp without sudo:
chgrp developers project.tar.gz
Special Permission Bits
The Sticky Bit
The sticky bit (octal 1000, shown as t in the execute position of "other") is most useful on shared, world-writable directories. It prevents users from deleting or renaming files owned by other users, even though they have write access to the directory itself. /tmp is the canonical example:
ls -ld /tmp
drwxrwxrwt 18 root root 4096 May 1 10:23 /tmp
Note the t at the end. Set it like this:
# Numeric: prepend a 1 to the three permission digits
sudo chmod 1777 /srv/shared
# Symbolic
sudo chmod +t /srv/shared
setuid and setgid (Brief Note)
Two other special bits exist. setuid (octal 4000) on an executable makes it run as the file's owner, not the calling user — this is how passwd can write to /etc/shadow. setgid (octal 2000) on a directory causes new files inside to inherit the directory's group automatically, which is handy for team project directories. Both deserve a dedicated guide; use them carefully.
Verifying Your Changes
# Human-readable permission string
ls -l filename
# Full detail including octal mode
stat filename
stat output includes a line like Access: (0644/-rw-r--r--) which shows the octal mode directly — useful when you're unsure what numeric value a file currently has.
Troubleshooting Common Issues
- "Permission denied" on a script you just created — New files are created without the execute bit. Fix with
chmod u+x script.sh. - Can't enter a directory even though you can see it — You're missing the execute bit on that directory. Execute on a directory means "traverse", not "run". Fix with
chmod o+x dirnameor adjust group membership. - Web server can't read files owned by your user —
www-dataornginxis the "other" class relative to your files. Either set other-read (chmod o+r), add the web server user to your group, or change ownership to the web server user. Never use777in production. - Files created in a shared directory get the wrong group — Apply setgid to the directory:
chmod g+s /srv/project. New files will inherit the directory's group regardless of the creator's primary group. - Recursive chmod broke directory traversal — If you ran
chmod -R 644on a tree, you removed execute from directories. Recover withfind /path -type d -exec chmod 755 {} +.
Frequently asked questions
- What is the difference between chmod 755 and chmod 644?
- 755 grants the owner full read/write/execute and everyone else read+execute — typical for directories and executable scripts. 644 grants the owner read+write and everyone else read-only — typical for regular data or config files that should not be executed.
- Why does the kernel use the owner bits even if they are more restrictive than the group bits?
- The kernel stops at the first matching class. If you own the file, only the owner bits apply; the group and other bits are ignored for you. This means a file with permissions 044 actually locks out its own owner.
- Can a normal user change a file's owner with chown?
- No. Only root (or a process with CAP_CHOWN) can transfer ownership to a different user. A regular user can change the group of a file they own, but only to a group they belong to, using chgrp.
- What does the sticky bit do on a file rather than a directory?
- On modern Linux kernels the sticky bit on a regular file has no practical effect. It was historically used to keep an executable in swap, but that behavior was removed decades ago. Its meaningful use today is solely on directories.
- How do I find all files on the system with world-writable permissions?
- Run 'sudo find / -xdev -perm -o+w -ls 2>/dev/null'. The -xdev flag prevents crossing filesystem boundaries, and -perm -o+w matches any file where the other-write bit is set regardless of the other bits.
Related guides
How to Back Up Your Linux System
Learn how to back up your Linux system using Timeshift, rsync, Borg, and Restic — then tie it all together with a practical 3-2-1 backup routine.
How to Choose a Linux Distribution
Match a Linux distro to your real needs — desktop, server, rolling vs LTS, hardware quirks, and package ecosystems — without wading through marketing noise.
How to Dual-Boot Linux and Windows
Shrink the Windows partition, install Linux without breaking the bootloader, configure GRUB, and handle Secure Boot — all in the correct order.
10 Things to Do After Installing Linux
Ten essential post-install steps for any Linux desktop: updates, drivers, firewall, codecs, backups, SSH hardening, and service cleanup — all with modern commands.