Skip to content
Part IA Lent Term

UNIX File Permissions

The 9-bit permission model

UNIX file permissions use a simplified ACL scheme with three fixed domains:

DomainRepresentationBits
User (owner)uRead, Write, eXecute
GroupgRead, Write, eXecute
Other (everyone else)oRead, Write, eXecute

Each file has a 9-bit permission mask, typically displayed as rwxrwxrwx (user/group/other). The kernel stores these bits in the file’s inode.

Octal representation

Permissions are commonly given in octal, where r = 4, w = 2, x = 1:

NumericBitsMeaning
7rwxRead + write + execute
6rw-Read + write
5r-xRead + execute
4r--Read only
0---No access

So chmod 640 file means: owner rw- (6), group r-- (4), other --- (0).

Special permission bits

BitOctalMeaning
SetUID (s)4000File executes with the owner’s UID, not the caller’s. Used by passwd, sudo
SetGID (s)2000File executes with the file’s group; on directories, new files inherit the directory’s group
Sticky bit (t)1000On a directory, only the file owner (or root) can delete or rename files — used on /tmp

SetUID is a powerful (and dangerous) mechanism: a SetUID root programme runs with full kernel privileges. Vulnerabilities in SetUID programmes are a classic privilege-escalation vector.

Access check algorithm

When process P tries to open file F for operation O:

  1. If P’s effective UID is 0 (root), access is granted unconditionally (unless the file system is mounted noexec or read-only, or the file is on NFS with root_squash).
  2. If P’s effective UID equals F’s owner UID, the owner permission bits are checked.
  3. Else, if P’s effective GID (or any supplementary group) equals F’s group GID, the group permission bits are checked.
  4. Else, the other permission bits are checked.

For directories, r permits listing, w permits creating/deleting entries, and x permits traversal (using the directory in a path).

The open-time check

UNIX checks permissions at open() time, not at each read() or write(). The returned file descriptor acts as a capability — once obtained, the process can use it until close() even if the file’s permissions are subsequently changed. This is efficient (check once, use many times) but means a process can retain access to a file whose permissions have been revoked, as long as it does not close and reopen the descriptor.

Performing the check on every read()/write() would be safer but more expensive, and would require handling the case where a descriptor becomes invalid mid-operation.

The root user

UID 0 (root) bypasses all permission checks. This is a convention implemented in the kernel, not a property of the permission bits. The username “root” is just a mapping in /etc/passwd; what matters is UID 0. If you change root’s UID to 1000, processes running under that UID lose special privileges, and the old UID 0 (now unnamed in /etc/passwd) retains them.


Past Paper Questions

2025 Paper 2 Question 3(c): Describe how an administrator might configure users, groups and file permissions to create files with specific permission patterns. [7 marks]

2025 Paper 2 Question 3(d): What happens if root’s UID is changed from 0 to 1000? [4 marks]