Permissions and Users · about 45 min

Octal modes, umask and directory permissions

Why this matters

You will constantly meet permissions written as numbers: chmod 600 ~/.ssh/id_ed25519, "the uploads directory must be 755", install -m 0644. You need to read and write that form as fast as the letters. You also need to know why new files get the permissions they get (the umask), and how permissions on directories work, because they behave differently from files and cause most of the genuinely confusing "Permission denied" errors.

Octal notation

Each permission triplet is three bits, and three bits make exactly one octal digit (0 to 7). Give each letter a value and add:

 r = 4    w = 2    x = 1

 rwx  r-x  r--
 4+2+1 4+0+1 4+0+0
   7    5    4      →  754
DigitLettersTypical use
7rwxowner of a directory or script
6rw-owner of a data file
5r-xothers on a directory or program
4r--others on a data file
0---no access

The modes you will see most:

ModeLettersUse
644rw-r--r--ordinary files
755rwxr-xr-xdirectories, programs, scripts
600rw-------private files (keys, passwords)
700rwx------private directories (~/.ssh)
640 / 750shared with a group, hidden from others

Octal chmod sets all nine bits at once, which is exactly what you want when you know the target state; symbolic chmod is better for "add or remove one thing, leave the rest":

$ chmod 640 report.txt
$ stat -c '%a %A %n' report.txt
640 -rw-r----- report.txt

A leading zero (0644) is allowed and means the same; a fourth digit in front sets the special bits described at the end of this lesson.

umask: the default permissions

Why do new files come out as 644 and new directories as 755? Programs ask the kernel for a mode when they create something: touch, editors and > redirections ask for 666 (rw for everyone), mkdir asks for 777. The kernel then removes the bits listed in the process's umask:

 requested   666  rw-rw-rw-          777  rwxrwxrwx
 umask       022  ----w--w-          022  ----w--w-
 result      644  rw-r--r--          755  rwxr-xr-x

The umask is a mask of bits to clear (formally mode & ~umask). It is not subtraction: a mask of 7 on a 6 gives 0, not -1. Open the shell for this lesson:

$ umask
0022
$ umask -S
u=rwx,g=rx,o=rx
$ umask 077
$ touch private.txt; mkdir privdir
$ ls -ld private.txt privdir
-rw-------. 1 learner learner 0 Nov  1 16:00 private.txt
drwx------. 1 learner learner 0 Nov  1 16:00 privdir
$ umask 022

Like the current directory, the umask is a per-process property, inherited by children, and umask is therefore a builtin. Setting it in a script affects only that script; to change your default, set it in ~/.bashrc or ~/.profile. Common values: 022 (others can read), 027 (others nothing), 077 (fully private).

Note that no umask produces an executable data file: since programs ask for 666, the x bits are never there to begin with. Compilers and chmod +x add them deliberately.

Directory permissions

A directory is a list of names. Its bits control operations on that list:

BitOn a directory it allows
rreading the list of names (ls)
wchanging the list: create, delete, rename entries (needs x too)
xsearching (traversing): using a name to reach its inode; cd into it; accessing anything below

The x bit is the important one. To open /work/site/public/index.html, the kernel resolves the path one component at a time (module 2), and it needs x on every directory along the way: /, /work, /work/site, /work/site/public. Then it checks the file's own r.

Try the combinations on a directory you own:

$ mkdir lab && echo hi > lab/f.txt
$ chmod 700 lab; ls lab; cat lab/f.txt
f.txt
hi
$ chmod 600 lab                     # r and w, no x
$ ls lab
ls: cannot access 'lab/f.txt': Permission denied
f.txt
$ cat lab/f.txt
cat: lab/f.txt: Permission denied
$ chmod 300 lab                     # w and x, no r
$ ls lab
ls: cannot open directory 'lab': Permission denied
$ cat lab/f.txt
hi
$ chmod 755 lab

Deleting is a directory operation

Remember from the last lesson: removing a file edits the directory, so it needs w and x on the directory, not any permission on the file. That leads to a security problem for shared directories like /tmp, where everybody needs w: anyone could delete anyone's files.

Special bits

A fourth octal digit, in front of the other three, holds three special bits. You will mostly read them rather than set them.

$ ls -ld /tmp /usr/bin/passwd
drwxrwxrwt. 1 root root      0 Nov  1 13:59 /tmp
-rwsr-xr-x. 1 root root 118168 Apr 19  2025 /usr/bin/passwd

This sandbox runs with "no new privileges", so even passwd cannot actually gain root here.

Capital X: execute only where it makes sense

A tree mixes directories (which need x) and data files (which should not have it). chmod -R a+x would make everything executable. The capital X adds execute only to directories and to files that already have an execute bit for someone:

$ chmod -R u=rwX,go=rX project/

That one line gives directories 755, ordinary files 644, and keeps scripts runnable. It is the correct way to "fix permissions" on a copied tree.

Common mistakes

Recap

Going further: run namei -l /work/site/public/index.html to see every permission along the path. Then find the setuid programs on this system: ls -l /usr/bin | grep '^-..s' (module 6 explains the pattern).

Exercises

Exercise 1 · quiz

Letters to digits

What is the octal (numeric) mode for rwxr-x---? Type the three digits.

Answer

Each triplet becomes one digit by adding r=4, w=2, x=1: rwx = 4+2+1 = 7, r-x = 4+1 = 5, --- = 0. So 750: the owner can do everything, the group can read and enter or run, others nothing. A typical mode for a script or directory shared with a team.

Exercise 2 · quiz

What will the new file get?

Your umask is 027. You create a new regular file with touch report.txt (touch asks for mode 666, as most programs do for data files). What mode does the file end up with?

Answer
  • 640

The umask lists bits to remove: 027 removes w (2) from the group and rwx (7) from others. 666 is rw-rw-rw-; taking away group w and all other bits leaves rw-r----- = 640. (Formally the result is requested & ~umask.) A new directory, requested with 777, would get 750.

Exercise 3 · quiz

Directory bits

A directory box has mode r-------- for you, its owner (read but no execute). Which of these work? Select all that apply.

Answer
  • ls box (list the names in it, possibly with errors about details)

On a directory, r lets you read the list of names, x lets you pass through it to reach the inodes behind the names (open files, cd into it, see their details), and w lets you change the list (create, delete, rename entries; this also requires x). With r alone, ls box can print the names but not stat them (you see ????????? with ls -l), and everything that needs to go through the directory fails.

Exercise 4 · task in a shell

Numeric modes

In /work/site, set these modes using octal chmod (for example chmod 700 name):

PathModeMeaning
site/private (directory)700only you can list, enter and change it
site/public (directory)755everyone can list and enter, only you change it
site/report.txt640you read/write, group reads, others nothing
site/deploy.sh750you everything, group read+execute, others nothing
site/public/index.html644everyone reads, you write

Check your work with ls -l site site/public or stat -c '%a %n' site/* site/public/*.

Hint 1

r=4, w=2, x=1; add them per triplet. chmod 700 private and so on.

Hint 2

Five commands: chmod 700 private, chmod 755 public, chmod 640 report.txt, chmod 750 deploy.sh, chmod 644 public/index.html (from inside site).

Reference solution
cd site
chmod 700 private
chmod 755 public
chmod 640 report.txt
chmod 750 deploy.sh
chmod 644 public/index.html

Exercise 5 · task in a shell

Enter but not list

/work/vault is a directory containing key.txt. Change the permissions of the directory vault (not of the file) so that, for you:

Try your idea, then test both commands yourself before pressing Check. (If you lock yourself out completely, you are still the owner: chmod 755 vault restores normal access.)

Hint 1

Listing a directory needs r on it; reaching a file through it needs x on it.

Hint 2

Remove read, keep execute: chmod u-r vault (or chmod 100 vault, or chmod 300 vault).

Reference solution
chmod 300 vault

Exercise 6 · write code

Watch umask work

Write a script that:

  1. sets the umask to 077,
  2. creates an empty file f1 (with touch) and a directory d1 (with mkdir),
  3. sets the umask to 022,
  4. creates an empty file f2 and a directory d2,
  5. prints the octal mode and name of all four with stat -c '%a %n' f1 d1 f2 d2.

Expected output:

600 f1
700 d1
644 f2
755 d2

File: script.sh

Starting point

umask 077

Example

expected output

600 f1
700 d1
644 f2
755 d2
Hint 1

umask is a builtin; it changes the mask of the current shell (here, the script's process) for everything created afterwards.

Hint 2

touch requests 666 and mkdir 777; the umask removes bits from that.

Reference solution
umask 077
touch f1
mkdir d1
umask 022
touch f2
mkdir d2
stat -c '%a %n' f1 d1 f2 d2