Memra

Permissions on directories

◈ 11 cards

What r, w and x mean on a directory, why r without x is nearly useless, and how to derive the minimal mode for a given operation.

A directory is a file of names, and that fixes the meanings

A directory is a file whose contents are a list of (name, inode) pairs. Once you accept that, the three bits stop being metaphors:

  • r — read the list. You may see the names in the directory.
  • w — write the list. You may create, delete or rename entries in it.
  • xsearch it. You may traverse it: cd into it, or resolve a pathname that passes through it, or stat any entry in it.

All the counter-intuitive behaviour follows from x being search rather than execute. Nothing about a directory is executable, and the bit is only called x because it shares a column with the file case.

Worked example — three broken directories, four different failures

Make three directories and set each to a deliberately incomplete mode:

$ chmod 600 alpha   # drw-------  read the names, cannot search
$ chmod 500 beta    # dr-x------  read and search, cannot write
$ chmod 300 gamma   # d-wx------  write and search, cannot read

Now watch four commands fail for four different reasons.

$ cd alpha
-bash: cd: alpha: Permission denied

No x. cd is a traversal, and traversal needs search permission, which 600 does not grant. On Linux ls alpha will still print the names — reading the list only needs r — but ls -l alpha cannot stat a single one of them, so the fields come back as errors. Names and nothing else is the whole of what r alone buys you, which is why the rule of thumb is that r without x accomplishes nothing useful.

$ touch beta/notes.txt
touch: cannot touch 'beta/notes.txt': Permission denied

No w. Creating an entry writes the directory’s list, and 500 is read-and-search only. cd beta and ls beta both work perfectly — this failure is nothing to do with reaching the directory.

$ ls gamma
ls: cannot open directory 'gamma': Permission denied
$ echo gamma/*
gamma/*

No r. 300 lets you go into gamma and create files there, but you cannot list what is already inside. The second line is the same failure wearing different clothes: globbing is done by the shell, and the shell needs r on the directory to read the names it is matching against. With no r, the pattern matches nothing and the shell hands the literal gamma/* through unchanged.

Now fix exactly one bit and re-run the first command:

$ chmod u+x alpha
$ ls -ld alpha
drwx------  2 ada  dev  4096 Sep  1 11:40 alpha
$ cd alpha
$

One bit. That is the shape of every directory-permission problem: name the operation, name the bit it needs, add that bit and nothing else.

Deletion is the directory’s business, not the file’s

Deleting alpha/report.txt does not modify report.txt — it removes a name from alpha’s list. So the permissions consulted are alpha’s, and they must include w (to edit the list) and x (to reach the entry at all). The minimum is therefore wx, which is octal 300d-wx------. The file’s own mode is irrelevant to whether the deletion is permitted: a file you cannot read, cannot write and do not own will disappear happily from a directory you have wx on. (rm will prompt before removing a file you lack w on, but that is a courtesy in the tool, not a permission check in the kernel — rm -f skips it.)

The reverse holds too. A file at mode 777 inside a home directory at 700 is unreachable by anyone but its owner: the traversal fails at the home directory, and the kernel never gets far enough to look at the file’s generous bits.

Every component, not just the last

A pathname is resolved one component at a time, and each directory in it needs x. /home/ada/projects/notes.txt requires search on /, on /home, on /home/ada and on /home/ada/projects. Setting chmod 755 projects achieves nothing if ada is 700 and you are not ada. That is why 711 is such a common mode for a home directory: it grants search without granting the ability to list what is inside.

biton an ordinary fileon a directoryrread the contentslist the names inside itwmodify the contentscreate, delete or renameentries in itxrun it as a program orscriptsearch it: cd into it, orresolve a name through itDeleting a file needs w+x on its DIRECTORY; the file’s own bits do not matter.
Same three bits, two entirely different vocabularies. The x column is where the exam marks are: on a directory it means search, not execute.
search okhome (711)x is set — you may pass throughdeniedprojects (600)no x — resolution stops herenotes.txt (777)unreachable by anyone but the ownerx is needed on every component, notonly the last.
The leaf is mode 777 and still nobody can open it. Resolution stops at the first component that lacks x, and no permission further down can undo that.
NORMAL ~/memra/learn/comp-325/permissions-on-directories utf-8 LF