0 / 8 flipped
What is a race condition?
A flaw that occurs when the outcome of a program depends on the sequence or relative timing of multiple operations accessing a shared resource. When two or more processes or threads race to access the same resource and the result depends on which reaches it first, the program's behaviour becomes unpredictable and potentially exploitable. Race conditions exist wherever a program assumes that state will not change between one operation and another β without enforcing that assumption.
What does TOCTOU stand for, and what does it describe?
Time-of-Check/Time-of-Use. It describes the specific race condition pattern where a program checks the state of a resource at one point in time (time of check) and then acts on it at a later point (time of use). If the resource changes between the check and the use, the program acts on stale information. TOCTOU is the exam term for this pattern β check, window, use. The window is where the attacker operates.
What is the race window, and why is even a tiny race window exploitable?
The race window is the time gap between a program's check and its use of a resource. Even a window of microseconds is exploitable because a modern computer can execute thousands of operations per second. An attacker running a replacement loop simultaneously with the vulnerable program will eventually land a replacement inside the window β often within seconds. The attacker only needs to win once. Automation makes even microsecond windows reliably hittable.
What is an atomic operation, and how does it prevent race conditions?
An operation that completes entirely in a single, uninterruptible step. There is no gap between check and use because they are one operation β no other thread can observe or modify the shared resource between the start and end of an atomic operation. Making the check-and-use atomic eliminates the race window entirely: the resource cannot change between check and use because check and use are the same indivisible step.
What is a mutex, and how does it prevent race conditions?
A mutual exclusion lock. Before accessing a shared resource, a thread acquires the mutex. While the lock is held, all other threads attempting to access the same resource are blocked. When the first thread finishes, it releases the lock and another thread may acquire it. A mutex prevents race conditions by ensuring only one thread can be in the check-use sequence at any moment β other threads must wait until the current thread completes its full check-and-use sequence.
What is deadlock, and why is it relevant to race condition prevention?
A situation where two or more threads each hold a resource the other needs and none can proceed. Thread A holds Lock 1 and waits for Lock 2; Thread B holds Lock 2 and waits for Lock 1 β both are permanently blocked. Deadlock is the failure mode of improper mutex usage. It doesn't breach security β it causes a denial of service, stopping the program entirely. Developers adding mutex locks to prevent race conditions must design locking carefully to avoid deadlock.
Describe the TOCTOU file symlink attack.
A privileged program checks whether a file has safe permissions (time of check), then writes to it (time of use). The attacker runs a loop replacing the target file with a symbolic link pointing to a sensitive system file. When the replacement lands between the check and the write, the program checks the original file (passes), then writes to the symlink's destination β a protected system file. The attacker used the race window to redirect a privileged write to a file they could not normally access.
What is a double-spend race condition, and how is it prevented?
A race condition in financial systems where two concurrent requests both pass the same balance check before either's debit is applied. Both read the balance, both see sufficient funds, both proceed β resulting in more money being spent than the account held. Prevention requires making the balance check and debit a single atomic database operation, typically using a transaction with row-level locking (SELECT ... FOR UPDATE) so that one request cannot read the balance until the other's debit is committed.