NOTE 002beginner13 min read

Linux permissions, visualized as operations

Stop memorizing 755. Read owner, group, and other permissions as answers to concrete file and directory operations.

FIG. 02 / INTERACTIVE MODEL

Directory permissions are capabilities

Change the selected identity and mode bits. The operation ledger explains the directory-specific result.

Directory mode bits
OwnerGroupOtherReadWriteExecute / search

Current directory mode

drwxr-xr-x0755
  • List entry names
  • Look up a known name
  • Create or remove an entry

Text equivalent

On a directory, read controls listing names, execute controls pathname search, and write plus execute controls creating or removing directory entries. The selected owner, group, or other class supplies one triplet; the kernel does not combine the three classes.

Figure note

This model intentionally omits ACLs, capabilities, read-only mounts, and sticky-directory ownership checks. Those can further restrict or permit an operation after the basic mode-bit choice.

rwxr-x--- is not a decoration and 750 is not a magic number. A mode is a small policy table: for a selected identity, which operations may proceed on this file or directory?

Model boundary: Traditional mode bits are only one authorization layer. POSIX ACLs, capabilities, immutable attributes, mount options, user namespaces, and security modules such as SELinux or AppArmor can change the outcome. The figure models owner/group/other mode bits so their semantics stay visible; it does not promise the final access decision.

Start with identity, object, operation

Three questions beat octal guessing:

  1. Which effective user and groups is the process using?
  2. Which object is it acting on—including every parent directory?
  3. Is the operation reading data, changing data, looking up a name, or changing a directory entry?

Inspect first:

id
stat -c '%A  %a  owner=%U  group=%G  %n' -- path/to/object
namei -l -- path/to/object

stat shows the target. GNU namei -l walks every pathname component, which is often the fastest way to find a missing directory search bit. If ACL tooling is installed, add getfacl -- path/to/object before assuming the nine mode bits tell the whole story.

Owner, group, and other are classes

The nine ordinary bits form three triplets:

          owner     group     other
symbolic   rwx       r-x       ---
octal       7         5         0

The file’s metadata records an owning user ID and group ID 1. The kernel selects the applicable permission class from the process credentials and object ownership; the classes are not three votes whose permissions are simply combined.

Names are conveniences. Access checks use numeric IDs, so a container, network filesystem, or restored backup can display a different name for the same number or no name at all.

The same letter means a different operation

This distinction prevents most permission mistakes.

Bit Regular file Directory
r Read file contents List directory-entry names
w Modify file contents Create, remove, or rename entries when search also permits it
x Request execution as a program Search/traverse; reach known names and metadata below it

Directory lookup happens component by component, and search permission is required along the path 2. Therefore:

  • A readable directory without x may reveal names but not let you stat or open those entries normally.
  • An executable/searchable directory without r can allow access to a known name without allowing a listing.
  • Deleting report.txt primarily changes its parent directory entry. The file’s own write bit is not the deciding bit.
  • Directory w is normally useful for entry mutation only alongside x.

Execution of a regular file still depends on a valid executable format or interpreter, searchable parent directories, and policies such as a noexec mount. An x bit is permission to attempt the operation, not a guarantee it succeeds.

Symbolic and octal are two views

Each octal digit is a bit sum: read 4, write 2, execute/search 1.

7 = rwx   6 = rw-   5 = r-x   4 = r--   0 = ---

Thus 640 means owner rw-, group r--, other ---. Symbolic changes describe intent and often make reviews safer.

Caution: chmod mutates authorization immediately. Confirm the exact target with stat or namei first. Avoid recursive mode recipes: files and directories need different execute semantics, and a broad traversal can cross unexpected content.

chmod u=rw,g=r,o= report.txt
chmod g+w shared-directory
chmod o-rwx private-directory

umask clears requested bits

Programs request a creation mode; the process umask clears bits from that request. It is a mask, not a default permission and not ordinary decimal subtraction 4.

Common starting requests are 0666 for regular files and 0777 for directories:

requested file       0666  rw-rw-rw-
umask                 0027  ----w-rwx  (bits to clear)
created mode          0640  rw-r-----

requested directory  0777  rwxrwxrwx
umask                 0027  ----w-rwx
created mode          0750  rwxr-x---

The creating program can request fewer bits or call chmod later. Default ACLs can also participate. Observe your shell’s current mask with umask and its symbolic form in shells that support umask -S.

Special bits solve narrower problems

The leading octal digit represents setuid (4), setgid (2), and sticky (1) 3.

  • Sticky directory: users may otherwise share write/search access, but entry removal and rename are restricted by ownership rules. /tmp is the familiar 1777 example.
  • Setgid directory: new entries commonly inherit the directory’s group; subdirectories may inherit setgid. This supports collaborative trees, with details affected by filesystem and mount behavior.
  • Setuid executable: a qualifying executable may run with an effective user ID derived from its owner. Linux ignores or clears this in several security contexts. It is a narrow privilege mechanism, not “run anything as root.”

Uppercase S or T in ls -l means a special bit is set while the corresponding execute/search bit is clear. That is state information, not merely typography.

A disposable directory lab

This lab shows why directory permissions are not file permissions. It uses only a newly created path and prints that path before mutation.

Caution: The following commands create files and change modes inside one mktemp directory. Read the printed path and run the block as one user; do not substitute a production path.

lab=$(mktemp -d)
printf 'lab=%s\n' "$lab"
mkdir "$lab/shared"
printf 'draft\n' > "$lab/shared/report.txt"

stat -c '%A %a %n' "$lab" "$lab/shared" "$lab/shared/report.txt"
chmod u=rwx,go= "$lab/shared"
stat -c '%A %a %n' "$lab/shared"

The final directory mode is 700: only its owner can list names, traverse it, or change its entries. The file mode did not need to change for the directory to become unreachable to other identities.

Clean up only the printed lab path:

rm -- "$lab/shared/report.txt"
rmdir -- "$lab/shared" "$lab"

SSH and web-service examples

For SSH, inspect the entire home-to-key path and file ownership before applying memorized numbers. OpenSSH deliberately refuses private key files accessible by others 6. A common private layout is searchable private directories and a private-key file readable only by its owner, but server configuration, ACLs, and platform policy remain authoritative.

For a web service, ask which service identity performs each operation:

  • Reading a static file needs file read permission plus search on every parent.
  • Creating an upload needs write and search on the destination directory.
  • Replacing a deployed file changes a directory entry; it is not granted by making the old file world-writable.

chmod 777 hides the identity question by granting every class broad access. It usually makes the model less clear and the system less safe.

Printable reference

FILE                 DIRECTORY
r  read bytes        r  list names
w  change bytes      w  add/remove/rename entries (normally needs x)
x  attempt execute   x  search/traverse known names

CLASS                OCTAL
u  owner             r=4, w=2, x=1
g  group             rwx=7, rw-=6, r-x=5, r--=4
o  other             special prefix: setuid=4, setgid=2, sticky=1

DEBUG ORDER
identity → every parent directory → target object → requested operation
→ ACL/capability/attribute → mount and security policy

Reference ledger

Primary sources

  1. Linux man-pages — inode(7)
  2. Linux man-pages — path_resolution(7)
  3. Linux man-pages — chmod(2)
  4. Linux man-pages — umask(2)
  5. GNU Coreutils manual — File permissions
  6. OpenBSD manual pages — ssh(1)