File permissions in Linux are the access rules, also called Unix permissions, that decide whether a process may read, write or execute a file or directory. Every file system object carries an owner, a group and a mode: nine permission bits arranged in three classes, owner, group and others, plus three special bits that change execution and deletion behavior.
Permissions are the foundation of the discretionary access control model in Linux. They are checked by the kernel on every open, execute and directory operation, and they are managed with tools such as chmod, chown, chgrp and umask, while finer rules can be added with ACLs.
How the kernel evaluates file permissions
When a process accesses a file, the kernel compares the process credentials with the file metadata stored in its inode. If the effective user ID matches the file owner, only the owner bits apply; otherwise, if one of the process groups matches the file group, only the group bits apply; otherwise the others bits apply. The check stops at the first matching class, so an owner with fewer rights than the group cannot fall back to group rights.
The root user bypasses read and write checks entirely through the CAP_DAC_OVERRIDE capability, and can execute a file if at least one execute bit is set. This is why permissions protect users from each other but not from an administrator, and why limiting root access with sudo matters.
The meaning of each permission differs between regular files and directories, as the following table shows.
| Permission | On a regular file | On a directory |
|---|---|---|
| Read (r) | View file contents | List the names of entries |
| Write (w) | Change file contents | Create, delete or rename entries |
| Execute (x) | Run as a program or script | Enter it and access entries by name |
A key consequence is that deleting a file depends on the directory, not on the file itself: a user with write and execute permission on a directory can remove a read-only file inside it, unless the sticky bit is set.
Symbolic and octal notation
Permissions are written in two equivalent notations. The symbolic form shown by ls -l, such as -rwxr-x---, lists the file type followed by three triplets. The octal form assigns 4 to read, 2 to write and 1 to execute and sums them per class, so rwxr-x--- becomes 750.
| Octal mode | Symbolic form | Typical use |
|---|---|---|
| 644 | rw-r–r– | Regular files readable by everyone |
| 600 | rw——- | Private files such as SSH keys |
| 755 | rwxr-xr-x | Programs and public directories |
| 700 | rwx—— | Private directories such as ~/.ssh |
| 775 | rwxrwxr-x | Shared group project directories |
| 1777 | rwxrwxrwt | Shared temporary directories such as /tmp |
The chmod command accepts both forms: chmod 640 report.txt sets an exact mode, while chmod g+w,o-r report.txt adjusts individual bits and leaves the others unchanged. Symbolic changes are safer for edits; octal modes are clearer for setting a known final state.
Special permission bits
Three additional bits extend the basic model and occupy the leading octal digit. They are powerful and are a frequent subject of security audits.
| Bit | Octal value | Effect | Example |
|---|---|---|---|
| setuid | 4000 | Program runs with the file owner’s user ID | /usr/bin/passwd |
| setgid on file | 2000 | Program runs with the file group’s ID | Some mail and terminal tools |
| setgid on directory | 2000 | New entries inherit the directory group | Team project folders |
| Sticky bit | 1000 | Only owners may delete their own entries | /tmp |
A setuid-root binary with a vulnerability can give an attacker full privileges, so administrators periodically list such files with find / -perm -4000 and remove the bit where it is not required. Linux ignores setuid on interpreted scripts for the same reason.
Default permissions and umask
New files do not receive a fixed mode. Programs request a mode, usually 666 for files and 777 for directories, and the kernel removes the bits set in the process umask. With the common umask of 022, new files become 644 and directories 755; with 027 they become 640 and 750, which hides content from other users.
Ownership is set at creation as well: the owner is the creating user, and the group is the user’s primary group unless the parent directory has the setgid bit. Ownership is changed later with chown and chgrp, and only root may give a file to another user.
The umask is a per-process setting inherited by child processes. It is usually set in shell startup files or with the UMask= directive of a systemd unit, so a service can create private files even when interactive users keep a more permissive default.
File permissions compared with other access controls
Classic permissions are deliberately simple, which is also their main limitation: each file has exactly one owner and one group. Linux therefore layers further mechanisms on top of them.
| Mechanism | Granularity | When to use it |
|---|---|---|
| Basic permissions | Owner, one group, others | Default for all files |
| POSIX ACLs | Named users and groups per file | Several teams need different rights |
| File attributes | Flags such as immutable | Protect critical files even from root mistakes |
| SELinux or AppArmor | Policy per process and label | Mandatory confinement of services |
| Capabilities | Individual root privileges | Replace setuid with narrower rights |
Common mistakes include using chmod 777 as a quick fix, which lets any local user alter or replace the file, forgetting the execute bit on directories in a path, and copying files with tools that do not preserve modes. Applying chmod -R with a file mode also strips execute permission from directories and breaks access.
In everyday language
File permissions work like the keys of an office building. Every file has an owner, a team and everyone else. For each of these three groups, the file says whether they may look at it, change it or run it.
A diary would be readable only by its owner. A team report could be edited by the team and only read by others. The computer checks these rules every time someone opens a file.
Seen in the real world
A small web agency hosts several client sites on one Linux server. Each site directory belongs to a deployment user and the www-data group, with mode 2750. The setgid bit makes uploaded files inherit the web group, the web server can read but not modify code, and other customers cannot browse the directory at all.
Upload folders that the application must write to receive mode 2770, and the deployment user’s umask is set to 027. During a security review, an auditor finds an old backup directory set to 777. Correcting it to 750 closes a path where any local account could replace scripts, without affecting the live sites.