File System Pitfalls

The file system controls access through owner, group, and other permissions. It also provides special permission bits including setuid, setgid, and the sticky bit.

Operating system security covers the kernel mechanisms that mediate these accesses.

setuid

The set-user-ID bit causes an executable to run with its owner’s effective user ID rather than the invoking user’s ID. A setuid program owned by root runs with root privileges.

A vulnerability in a privileged program can therefore grant the attacker the program owner’s privileges.

Time-of-Check to Time-of-Use

A time-of-check to time-of-use vulnerability occurs when a file changes after validation but before use. The file system is asynchronous, so a pathname can resolve to a different object between separate operations.

It violates complete mediation because the checked object is not necessarily the object later used.

if (access(path, R_OK) == 0) {
  FILE *file = fopen(path, "r");
}

An attacker can replace path with a symbolic link after access succeeds and before fopen runs. The process then reads a different file. The impact is severe when the program has elevated privileges.

Time-of-check to time-of-use race A privileged program checks a safe file. An attacker replaces its pathname with a symbolic link before the program opens it, causing it to open a protected file instead. Privileged program File system Attacker check: safe.txt allowed replace path with symlink open path opens protected file
The attacker changes the pathname in the gap between the check and the later open operation.

Prevention

  • Do not use access to authorize a later file operation.
  • Open the file once and validate the returned file descriptor.
  • Use open flags such as O_NOFOLLOW, where appropriate.
  • Use descriptor-relative operations such as openat to constrain path resolution.
  • Create temporary files with mkstemp rather than predictable names.
Written by October 30, 2026 2 min read
Was this helpful?