Skip to content

Time of check to time of use

Category: Hazards · Status: stub · Lessons: chapter 02, Shared state

One line: Checking a condition and then acting on it as two separate steps, so that the condition can change in between — the classic check-then-act race.

Also called: TOCTOU, TOCTTOU, check-then-act.

How it connects

flowchart LR
  n_compare_and_swap["Compare-and-swap"]
  n_mutual_exclusion["Mutual exclusion"]
  n_race_condition["Race condition"]
  n_toctou["Time of check to time of use"]
  n_compare_and_swap -->|prevents| n_toctou
  n_mutual_exclusion -->|prevents| n_toctou
  n_toctou -->|is a| n_race_condition
  classDef center stroke-width:3px
  class n_toctou center
  classDef outside stroke-dasharray: 4 3
  class n_compare_and_swap,n_mutual_exclusion,n_race_condition outside

In each language

Rust Path::exists warns of TOCTOU bugs, and says try_exists cannot prevent them either
C fopen: the x flag makes w fail if the file already exists, so the check and the create are one step
C++ std::ios_base::noreplace (C++23) opens a file in exclusive mode
Java Files.createFile checks for the file and creates it as a single atomic operation; ConcurrentHashMap.putIfAbsent does the same for a map entry
Python os.access warns that checking before open() creates a security hole in the interval between the two
The operating system access(2) ↗ gives the same warning: the time between checking and open(2) can be exploited

Where to read more