← All concepts
Linux

Linux file permissions, from rwx to capabilities

What ls -l is really telling you — and how the bits decide who can do what.

15 min read · updated 20 Jun 2026
This concept is explained in five layers — from a simple analogy up to a deep technical dive. Read top-to-bottom, or jump to your level.
On this page
Level 1·The clubhouse rules

Explain like I'm 5

Every file in Linux is like a little clubhouse with a sign on the door. The sign answers two questions: who is this about, and what are they allowed to do?

There are three kinds of who: you (the owner), your group (your friends), and everyone else. And three kinds of what: look at it (read), change it (write), and use/run it (execute).

In one line

Linux permissions answer “what can the owner, the group, and everyone else each do — read, write, or execute — to this file?”

Level 2·Reading ls -l

Beginner

Run ls -l and you get lines like this:

$ ls -l report.txt
-rw-r--r-- 1 alice staff 4096 Jun 20 09:14 report.txt

That first column, -rw-r--r--, is the permissions. Read it in four chunks:

ChunkMeaning
-File type: - file, d directory, l symlink.
rw-Owner (alice): read + write, no execute.
r--Group (staff): read only.
r--Other (everyone else): read only.

The three permission bits are always in the order r (read), w (write), x (execute); a - means that permission is off. After the permissions, alice staff are the owning user and owning group.

You change permissions with chmod, and ownership with chown:

chmod g+w report.txt        # add write for group
chown alice:devs report.txt # set owner alice, group devs
Level 3·Octal, directories, and umask

Intermediate

Each permission has a number: read = 4, write = 2, execute = 1. Add them per group and you get the familiar three-digit octal mode.

Owner = 7
r4
w2
x1
Group = 5
r4
w2
x1
Other = 5
r4
w2
x1
chmod 755 — owner rwx (4+2+1), group r-x (4+1), other r-x (4+1). A common mode for executables and directories.
Execute means something different on a directory

On a file, x means run it as a program. On a directory, x means you may traverse into it (cd, and access files by name). So a directory often needs r-x: r to list its contents, x to enter it. Read without execute on a directory is nearly useless.

PermissionOn a fileOn a directory
rread contentslist the names inside
wmodify contentscreate/delete/rename entries
xexecute as a programenter/traverse (access entries by name)

umask controls the default permissions of newly created files. It's a mask of bits to remove from the base mode (666 for files, 777 for directories). The common 022 yields 644 files and 755 directories.

The recursive chmod footgun

chmod -R 755 . on a source tree is a classic mistake: it stamps the execute bit onto every file, not just directories. Use the capital Xchmod -R u+rwX,go+rX . — which adds execute only to directories and files that are already executable. It does the right thing for both at once.

Both calculations are fiddly by hand — the chmod calculator and umask calculator do them instantly.

Level 4·Special bits and ACLs

Advanced

Beyond the nine basic bits there's a fourth octal digit for special bits, and they're where a lot of subtle behaviour (and risk) lives.

BitOctalEffect
setuid4000An executable runs with the owner's privileges, not the caller's. passwd uses this to edit /etc/shadow as root.
setgid2000On a binary: run as the owning group. On a directory: new files inherit the directory's group — great for shared project folders.
sticky1000On a directory: only a file's owner (or root) can delete it, even if others can write. This is why anyone can create files in /tmp but not delete each other's.

In a long listing these appear in the execute column: s (setuid/setgid with execute), S (set but no execute), t/T (sticky). For example /tmp shows drwxrwxrwt.

ACLs (Access Control Lists) extend the model when plain user/group/other isn't enough — for example granting one extra user write access without changing the group. A + at the end of the mode in ls -l signals ACLs are present.

setfacl -m u:bob:rwx project/   # give bob rwx, no group change
getfacl project/                # view the ACL

# the trailing + means ACLs are set:
# drwxr-xr-x+ 2 alice devs 4096 ... project
Per-user access with ACLs
Default (inherited) ACLs

A default ACL on a directory (setfacl -d -m u:bob:rwx project/) is inherited by everything created inside it later — the closest Linux gets to Windows-style inheritance. It's the clean way to make a shared project directory where new files are automatically accessible to a team, without relying on setgid + umask gymnastics.

Level 5·Security, setuid risk, and capabilities

Deep dive

Permissions are a core part of Linux security, and a few patterns are classic findings in any audit.

The dangers

World-writable files (o+w) let any user tamper with them — catastrophic for scripts or config that run as root. Rogue setuid-root binaries are a top privilege-escalation vector: a bug in a setuid-root program runs with root power. Hunt for both regularly.

# Every setuid-root binary on the system
find / -perm -4000 -user root -type f 2>/dev/null

# World-writable files (excluding symlinks)
find / -xdev -type f -perm -0002 2>/dev/null

# World-writable directories without the sticky bit (risky)
find / -xdev -type d -perm -0002 ! -perm -1000 2>/dev/null
Finding risky permissions

How it works under the hood. Every process has a UID/GID (and effective UID/GID). When you open a file, the kernel compares your effective IDs against the file's owner/group/other bits, in that order, and grants the first matching class. That's why if you're the owner, the group and other bits never apply to you — even if they're more permissive.

Capabilities — the modern alternative to setuid-root

Instead of giving a program all of root via setuid, Linux capabilities grant just the slice it needs. ping no longer needs setuid-root — it only needs CAP_NET_RAW. Set with setcap cap_net_raw+ep /usr/bin/ping; inspect with getcap. Smaller blast radius if the binary is exploited.

Beyond permissions: the immutable bit

Some protections live in filesystem attributes, not the permission bits. chattr +i file makes a file immutable — even root cannot modify or delete it until chattr -i clears the flag (check with lsattr). Handy for locking down config or audit logs, and a favourite hiding spot for malware persistence, so it's worth knowing it exists.

Note too that inside a container, UID 0 may be mapped to an unprivileged host UID via a user namespace, so "root" in the container has none of root's power on the host — the permission model still applies, just remapped (see how containers work).

Worth knowing that Mandatory Access Control (SELinux, AppArmor) layers on top of these discretionary permissions. Even if the rwx bits would allow an action, an SELinux policy can still deny it — which is why ls -l looks fine but access is refused, and why you check ausearch/dmesg for denials.

The one-paragraph summary

Linux permissions grant read/write/execute to three classes — owner, group, other — checked first-match by the kernel against a process's effective UID/GID. Octal modes encode them (r=4, w=2, x=1); umask sets defaults; setuid/setgid/sticky add special behaviour; ACLs and capabilities add precision; and MAC (SELinux/AppArmor) can override it all. Most security incidents trace back to world-writable files or careless setuid-root binaries.

Frequently asked questions

What does chmod 755 mean?

Owner gets read+write+execute (7 = 4+2+1), group gets read+execute (5 = 4+1), and other gets read+execute (5). It's a common mode for executables and directories that everyone may use but only the owner may modify.

What's the difference between execute on a file and on a directory?

On a file, execute means you can run it as a program. On a directory, execute means you can traverse into it and access files by name. To list a directory's contents you also need read; to enter and use it you need execute.

What is the sticky bit used for?

On a directory, the sticky bit restricts deletion so that only a file's owner (or root) can remove it, even when others have write permission. The classic example is /tmp, which is world-writable but has the sticky bit so users can't delete each other's files.

What does umask 022 do?

umask removes permission bits from the default base mode. With 022, the group and other write bits are removed, so new files default to 644 (rw-r--r--) and new directories to 755 (rwxr-xr-x).

Why can't I access a file even though the permissions look right?

Common causes: you lack execute (traverse) permission on a parent directory in the path; an ACL or the first-match class rule applies different bits than you expect; or a Mandatory Access Control system like SELinux/AppArmor is denying it regardless of the rwx bits. Check the full path's permissions and the audit log.

ShellQuest turns concepts like this into bite-sized lessons, puzzles and labs you actually practise.

Join the waitlist