Race conditions (TOCTOU - Time-of-Check Time-of-Use) are software vulnerabilities that occur when the behavior of a program depends on the sequence or timing of uncontrollable events (thread execution order, I/O completion, signal delivery). Attackers exploit race conditions by manipulating timing to create a discrepancy between the "check" (access, stat) and "use" (open, read, write) phases. Race conditions lead to privilege escalation (reading /etc/shadow), file corruption, data tampering, or denial of service. 20% of kernel vulnerabilities are race conditions (CVE database).
Race Condition Statistics: 20% of kernel vulnerabilities are race conditions. 60% of TOCTOU vulnerabilities are in file operations (access/open, stat/open). 40% of race conditions occur in multi-threaded applications. Average CVSS score: 7.0 (High).
Common race condition attack vectors:
Attacker exploits window between access check (stat, access) and file use (open, read, write). Replace file with symlink or malicious content during race window.
Multiple threads accessing shared data without proper locking (mutex, semaphore). Leads to data corruption, memory corruption, or privilege escalation.
Signal handler interrupts non-reentrant functions (malloc, printf). Leads to memory corruption or crashes.
Attacker creates symlink during race window. Program follows symlink to sensitive file (/etc/passwd, /etc/shadow). Privilege escalation.
// TOCTOU race condition example (access() then open())
// Vulnerable code (setuid binary)
if (access("/tmp/tempfile", W_OK) == 0) {
// Race window! Attacker replaces /tmp/tempfile with symlink to /etc/shadow
int fd = open("/tmp/tempfile", O_WRONLY);
write(fd, user_data, strlen(user_data));
close(fd);
}
// Exploit script (symlink race)
while true; do
ln -sf /tmp/real_file /tmp/tempfile
ln -sf /etc/shadow /tmp/tempfile
done
// Multi-threaded race condition (shared counter)
int counter = 0;
void* increment(void* arg) {
for (int i = 0; i < 1000000; i++) {
counter++; // Not atomic! Race condition
}
return NULL;
}
// Expected: 2,000,000
// Actual: 1,234,567 (race condition - lost updates)
Race condition in Linux kernel memory subsystem (copy-on-write). Local privilege escalation (user → root). Allowed writing to read-only memory mappings. Affected all Linux kernels (2007-2016).
Race condition in sudo (setuid binary). Allowed users to bypass sudo restrictions and execute arbitrary commands. Affected sudo versions 1.8.20p1 and earlier.
TOCTOU race condition in Docker. Allowed attackers to escape containers and access host filesystem. Symlink race in docker cp command.
Race condition in mmap syscall. Privilege escalation via userfaultfd. Affected Linux kernels before 4.13.10.
// Race condition statistics (CVE database, 2023-2024)
- 20% of kernel vulnerabilities are race conditions
- 60% of TOCTOU vulnerabilities are in file operations (access/open, stat/open)
- 40% of race conditions occur in multi-threaded applications
- 30% occur in file system code (kernel)
- 20% occur in network code (socket races)
- 10% occur in signal handlers
- Average CVSS score: 7.0 (High)
- 50% of race conditions lead to privilege escalation (user → root)
- 30% lead to denial of service
- 20% lead to information disclosure
// Most affected software categories
1. Operating systems (Linux kernel, Windows kernel): 40%
2. File system utilities: 25%
3. Database systems: 15%
4. Network daemons: 10%
5. Web servers: 10%
This demonstration simulates a TOCTOU race condition between access() and open():
This is a simulated demonstration. Real race conditions (TOCTOU) exploit the timing window between check (access) and use (open). Defenses: Atomic file operations (openat2, O_TMPFILE), proper locking (flock, fcntl), avoid TOCTOU (open with O_NOFOLLOW, O_EXCL). Use ThreadSanitizer (TSan) to detect data races.
Clang/GCC -fsanitize=thread detects data races at runtime. Identifies unsynchronized concurrent memory accesses.
Detects race conditions in multi-threaded programs. Analyzes lock usage (mutex, semaphore).
Valgrind tool for detecting race conditions. Tracks memory accesses across threads.
Static analysis detects potential TOCTOU vulnerabilities (access then open). Flags unsafe file operations.
Use openat2 with RESOLVE_NO_SYMLINKS, RESOLVE_IN_ROOT. O_TMPFILE creates anonymous file (no TOCTOU).
Protect shared data with mutex locks. Use pthread_mutex_lock/unlock. Avoid double-check locking.
Open with O_NOFOLLOW (don't follow symlinks). O_EXCL ensures exclusive creation (atomic mkstemp).
Check permissions during open (EACCESS). Don't call access() before open(). Use faccessat() with AT_EACCESS flag.
Best Practice - Use Atomic Operations + Proper Locking: Use atomic file operations (openat2 with RESOLVE_NO_SYMLINKS, O_TMPFILE). Avoid TOCTOU (don't call access() before open()). Use proper locking (mutex, semaphore) for shared data. Use ThreadSanitizer (TSan) to detect data races. Enable compiler warnings (-Wthread-safety).
Race condition exploits are illegal when used without authorization (CFAA). Ethical uses include:
Race condition exploits are illegal when used without authorization. Penalties include:
Important: This guide is for educational and defensive purposes only. Only test race conditions on systems you own or have explicit written authorization. Responsible disclosure to vendors.
Technical analysis of Linux kernel race condition (copy-on-write). Privilege escalation exploit.
Dynamic race condition detection tool (-fsanitize=thread).
Race condition detection for multi-threaded programs.