OnCallReady

Lesson 4.5 · Filesystem, Permissions, Disk · 20 min read

Permission bits and octal

In plain words

Imagine a box with three locks on its lid, one for the owner, one for the owner's team, and one for everyone else. Each lock has three switches: "may look inside" (r), "may change what is inside" (w), "may use it as a tool" (x). When someone walks up, the box checks only one lock: the owner's if it is the owner, otherwise the team's if they are on the team, otherwise everyone's.

That is -rwxr-x---. Octal is a shorthand: look = 4, change = 2, use = 1, added up per lock, so 750 is owner 7 (4+2+1), team 5 (4+1), everyone 0. chmod 640 notes.txt sets exact switches; chmod g+r flips one on. chown root:ops decides who the owner and team are.

Why you need to read these nine letters

A secrets file readable by every user, a script anyone can edit, a service that cannot read its own config - all three are the same nine letters in ls -l, set wrong. Reading them at a glance, and setting them exactly, is daily work.

What you need to know already: 1.3 (ls -la), 4.3 (users, groups, sudo -u).

Three triples

Every file has an owner (one user), a group (one group), and a mode: nine permission bits saying what each kind of visitor may do.

-rwxr-x---  1 root ops  87 Sep 22 20:00 deploy.sh
 │└┬┘└┬┘└┬┘
 │ │  │  └── other: everyone else - no access at all
 │ │  └───── group (ops): read + execute
 │ └──────── user (the owner, root): read + write + execute
 └────────── type: - file, d directory, l symlink, c/b device

r read the contents, w change them, x execute (run it as a program). A - in a slot means that bit is off. Each group of three is called a triple.

Octal: the same bits as three digits

Writing modes as digits is called octal (base 8, digits 0-7). Each bit has a value - r=4, w=2, x=1 - and you add them up per triple:

750 = rwx r-x ---     a script the owner runs and a group may run
640 = rw- r-- ---     a config file the group may read
600 = rw- --- ---     a secret
644 = rw- r-- r--     a normal world-readable file
755 = rwx r-x r-x     a normal program or directory
700 = rwx --- ---     a private directory (~/.ssh)

To convert by hand, do one triple at a time: r-x = 4+0+1 = 5, rw- = 4+2+0 = 6. Going the other way, 6 can only be 4+2 (rw-), 5 only 4+1 (r-x), 3 only 2+1 (-wx). There is exactly one way to write each digit, which is why octal works.

Two habits: 600 for anything with a credential in it, and never 777 for anything. 777 on a script does not fix a problem, it advertises one - and it is the first thing an auditor looks for. ("World-readable" / "world-writable" means the other triple has r / w.)

Which triple applies - exactly one

The kernel picks one triple and ignores the other two:

  1. You are the file's owner -> the user triple. Full stop.
  2. Else, the file's group is one of your groups -> the group triple.
  3. Else -> the other triple.

It does not "add up" your best option. An owner with fewer rights than the group gets the owner's rights:

$ cd /tmp; echo 'Q3 numbers' > report.txt; chgrp ops report.txt; chmod 060 report.txt
$ ls -l report.txt
----rw---- 1 learner ops 11 Sep 22 20:00 report.txt
$ cat report.txt
cat: report.txt: Permission denied
$ sudo -u appuser cat report.txt       # appuser is in ops
Q3 numbers

(chgrp ops FILE sets the file's group; chmod MODE FILE sets its mode - both below.) You own it, so your triple (---) is the only one checked, even though you are also in ops. Root skips all of this for reading and writing - but not for executing: root can run a file only if at least one x bit is set anywhere.

chmod both ways

chmod ("change mode") takes either octal or a symbolic change - who (u owner, g group, o other, a all), then + add, - remove or = set exactly, then the bits:

chmod 750 deploy.sh          absolute - set exactly these bits
chmod u+x script.sh          symbolic - add execute for the owner
chmod go-w file              remove write from group and other
chmod a=r file               everyone gets exactly read
chmod u=rwx,g=rx,o= file     a whole mode, spelled out (= 750)
chmod -R g+rX dir            -R recursive (the whole tree). Capital X means
                             "x only on directories and on files that
                             already have some x" - what makes -R safe

Watch each form change the same file:

$ echo hi > f; ls -l f
-rw-r--r-- 1 learner learner 3 Sep 22 20:00 f
$ chmod 640 f; ls -l f
-rw-r----- 1 learner learner 3 Sep 22 20:00 f
$ chmod u+x,g-r f; ls -l f
-rwx------ 1 learner learner 3 Sep 22 20:00 f
$ chmod a= f; cat f
cat: f: Permission denied
$ chmod o+w f; stat -c '%a %A %U:%G %n' f
002 --------w- learner:learner f

Symbolic changes are relative - they add or remove bits and leave the rest. Octal is absolute - it replaces everything. Use symbolic when you mean "also let the group read", octal when you mean "this file must be exactly 640".

chmod -R 755 dir makes every text file executable, which is noise at best and a security finding at worst. chmod -R g+rX is what you meant.

chown

chown ("change owner") sets the owner, the group, or both:

sudo chown appuser file           owner
sudo chown appuser:appgroup file  owner and group
sudo chown :ops file              group only (same as chgrp)
sudo chown -R root:ops /srv/ops   recursive
sudo chgrp ops file               group only

Only root can give a file away. The usual pattern for a shared team directory is root:ops ownership with the group bits doing the work, so no human owns it and membership of ops is the access control.

The errors, and what each one means

$ chmod 644 /etc/passwd
chmod: changing permissions of '/etc/passwd': Operation not permitted
$ chown root f
chown: changing ownership of 'f': Operation not permitted
$ chmod 999 f
chmod: invalid mode: '999'
Try 'chmod --help' for more information.

Reading it back

stat prints everything the filesystem stores about a file:

$ stat -c '%a %U:%G %n' /srv/ops/*
750 root:ops /srv/ops/deploy.sh
640 root:ops /srv/ops/notes.txt
600 root:ops /srv/ops/secrets.env
$ stat /etc/passwd
  File: /etc/passwd
  Size: 969       	Blocks: 8          IO Block: 4096   regular file
Device: 252:0	Inode: 1066        Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

stat -c FORMAT prints only what you ask for: %a octal mode, %A the rwx string, %U/%G owner and group names, %u/%g their numbers, %n the name. Scripts and checks compare these numbers, not ls output. (The Inode and Links fields are 4.13.)

What you can now do

Why it helps

Every "Permission denied" starts with reading a mode string, and every security review includes permission findings: a private key at 644, a secrets file readable by other, a script at 777, a config directory writable by a service user. Being able to read -rw-r----- as 640 instantly, and knowing which triple applies to whom, makes those conversations quick and precise.

It also prevents self-inflicted incidents: chmod -R 755 making every file executable, or a recursive chmod that removes x from directories and breaks an application. chmod -R g+rX and stat -c '%a' in scripts and checks are the correct tools. The only-one-triple rule explains the surprising case where the owner has fewer rights than the group.

Commands in this lesson

stat cd ls cat touch echo chmod chown

FAQ

What does capital X mean in chmod?

X sets execute only on directories and on files that already have at least one execute bit. So chmod -R g+rX dir makes directories traversable and existing programs runnable for the group, without making every text file executable. It is the flag that makes recursive chmod safe. Lowercase x would mark all files executable.

Why can root read a file with mode 000 but not execute it?

Root bypasses read and write permission checks through the CAP_DAC_OVERRIDE capability. For execute, the kernel still requires at least one execute bit to be set on a regular file, somewhere in the mode, even for root. The idea is that a file with no execute bits is not a program, so running it is almost certainly a mistake.

Why does chmod say Operation not permitted when I can write to the file?

Changing a file's mode is a right of its owner (and root), not of anyone who can write to it. Write permission lets you change the content, not the metadata. The error is EPERM, "Operation not permitted", rather than EACCES. Similarly, only root can change a file's owner, and an owner can change the group only to one of their own groups.

Should I use octal or symbolic chmod?

Use octal when you mean an exact final state, like "this secret must be 600", which is also easier to check in scripts. Use symbolic when you mean a change relative to what is there, like "also let the group read" (g+r) or "nobody else may write" (o-w), without disturbing the other bits. Configuration management usually specifies octal modes.

What mode should an SSH private key or a secrets file have?

600: read and write for the owner, nothing for anyone else. SSH refuses to use a private key readable by others ("UNPROTECTED PRIVATE KEY FILE"), and ~/.ssh should be 700. For secrets that a service reads through a group, 640 with a dedicated group works. Anything more open for a credential is a finding in any review.

In an interview Junior

What does chmod 754 mean, and how does Linux decide which permissions apply to you?

Each digit is one triple, adding r=4, w=2, x=1: owner 7 = rwx, group 5 = r-x, others 4 = r--. As a string, -rwxr-xr--.

The kernel picks exactly one triple and ignores the others:

  1. you own the file -> the owner triple, full stop;
  2. else the file's group is one of your groups -> the group triple;
  3. else -> others.

It does not add up your best option: a file ----rw---- that you own is unreadable to you, even if you are in its group. Root skips read and write checks, but needs some x bit to execute.

chmod 640 f sets the mode absolutely; chmod g+r f changes only the bits you name. chown appuser:ops f sets owner and group (only root may give a file away). Verify with stat -c '%a %U:%G %n' f.

Also asked: A developer ran chmod -R 777 to fix a permission error. What is wrong with that, and what would you do instead? · What is the difference between "Operation not permitted" and "Permission denied"? · What does the capital X in chmod -R g+rX do?

Practise this lesson in the terminal Free, in your browser - a real Ubuntu terminal to try it in, with missions that check your work.