A TOCTOU Race Condition

Time-Of-Check to Time-Of-Use. Between the check (T1) and the use (T2), an attacker swaps the file out from under a privileged process.

Legitimate actor / call Attacker action Critical window (the race)
sequenceDiagram autonumber participant P as Privileged Process participant F as Filesystem participant A as Attacker Note over P: T1 — TIME OF CHECK P->>F: access("/tmp/x", R_OK) F->>P: OK — normal user-owned file rect rgb(255, 205, 210) Note over P,A: TOCTOU window — the file is no longer what was checked A->>F: unlink("/tmp/x") A->>F: symlink("/etc/shadow", "/tmp/x") end Note over P: T2 — TIME OF USE P->>F: open("/tmp/x", O_RDONLY) F->>P: fd for /etc/shadow (symlink followed) Note over P: Privileged process reads /etc/shadow
Structural fix: close the window instead of trying to shrink it. Use openat() with O_NOFOLLOW, or open the file once and operate on the file descriptor (fstat, not stat) — then the thing you checked and the thing you use are guaranteed to be the same object.

Back to Documentation