Race Conditions & TOCTOU

Last updated: 2026-04-10
Related: Use After Free, Architecture
Tags: race-condition, user-mode, kernel-mode

Summary

Race condition vulnerabilities arise when a security-critical operation assumes exclusive access to shared state but can be interrupted between a check and an action. In Windows, the most exploitable patterns are TOCTOU (Time-Of-Check-Time-Of-Use) in file/object operations, double-fetch bugs between user-mode and kernel-mode, and concurrent access to kernel objects. These bugs can yield arbitrary write primitives, privilege escalation, or sandbox escapes.


TOCTOU (Time-Of-Check-Time-Of-Use)

Pattern

1. CHECK: kernel validates user-supplied buffer/path/handle
2.        ← RACE WINDOW: attacker modifies the checked resource
3. USE:   kernel uses the now-modified resource assuming validation holds

Classic: File Path TOCTOU

1. Kernel: check if path "C:\User\file.txt" is safe
2. Attacker: rename symlink/directory → path now points to "C:\Windows\System32\file.txt"
3. Kernel: opens/writes to privileged path assuming prior check was valid

CVE Examples

  • CVE-2015-1701 (TOCTOU in Client/Server Runtime): CreateSymbolicLink race → arbitrary file operation as SYSTEM
  • CVE-2018-0743 (WSL TOCTOU): Windows Subsystem for Linux path race
  • Stuxnet used a 0-day print spooler TOCTOU
  • PrintNightmare variants (2021) — spooler TOCTOU on driver path validation

Double-Fetch Bugs

A kernel reads a user-mode value twice without re-validation — attacker modifies it between reads.

// Vulnerable kernel code:
ULONG size = *(ULONG*)UserBuffer;     // FETCH 1: read size
if (size > MAX_SIZE) return ERROR;    // check using size
// ...
ULONG size2 = *(ULONG*)UserBuffer;   // FETCH 2: attacker changed UserBuffer[0] here!
memcpy(kernel_buf, src, size2);       // use size2 → heap overflow

Why this happens:

  • Performance optimization: reading from user memory is “cheap”
  • Incorrect assumption that user memory is stable
  • Missing ProbeForRead + copy-to-kernel-buffer pattern

Exploitation

  • Thread 1: call vulnerable syscall with size = VALID
  • Thread 2: spin loop writing size = HUGE to buffer address
  • Race: kernel reads valid size, checks pass, re-reads huge size, copies too much

Tools: write racing thread that continuously modifies the value; usercallback fuzzing

CVE Examples

  • CVE-2016-7255 (win32k double-fetch) — used in-the-wild by APT28
  • CVE-2013-3660 (win32k, BITMAP double-fetch) — used in targeted attacks

Kernel UAF via Concurrent Object Manipulation

When two threads operate on the same kernel object concurrently:

Thread A: begin_operation(obj)       ← increments refcount or takes lock
Thread B: destroy(obj)               ← if refcount check has race, frees obj
Thread A: use(obj)                   ← obj already freed → UAF

win32k Callback Races

Win32k’s callback mechanism (calling user-mode during kernel operations) creates race windows:

Thread 1: win32k starts operation, calls user-mode callback
Thread 2: during callback, destroys shared win32k object
Thread 1: returns from callback, accesses freed object → UAF

This is the root cause of many win32k UAF CVEs (see Use After Free).


File System Races

Opportunistic Lock (OpLock) Races

  • Request an OpLock on a file before a privileged process opens it
  • When privileged process opens → OpLock callback to user-mode
  • During callback: rename file, replace with symlink to privileged location
  • Release OpLock → privileged process now operates on attacker-chosen file

CVE-2019-0841: Windows AppX installer TOCTOU via OpLock → DACL manipulation on privileged file → SYSTEM

  • NtCreateFile with FILE_FLAG_OPEN_REPARSE_POINT + directory junction
  • Windows supports object manager symlinks (\??\C:\...)
  • Mount points + junctions can redirect file operations
  • Combined with privileged process writing to “safe” path → redirect to system path

Tools:

  • CreateMountPoint.exe (Tyranid/James Forshaw)
  • NtApiDotNet symbolic link primitives
  • symboliclink-testing-tools — James Forshaw’s PoC tools

Semaphore / Lock Order Inversions

Deadlocks that degrade into races when locks are bypassed or ordered incorrectly:

  • Lock A → Lock B (correct order)
  • Thread 2: Lock B → Lock A (inverted)
  • Result: race window between partial lock acquisition

In kernel: lock order violations in IRP handling, I/O completion paths, and DPC routines.


Exploitation Techniques

Winning the Race: Timing Strategies

  1. CPU core pinning: pin racing threads to specific cores for reproducible scheduling
  2. Priority manipulation: boost racing thread to just above vulnerable thread
  3. Pause sliding: use RDTSC-based spinning to align execution windows
  4. Event synchronization: use kernel events to synchronize entry into race window
  5. Large race window: prefer bugs where window spans a syscall (much larger window)

Kernel-Specific Race Amplification

  • Use NtSetInformationThread(ThreadPriority) to control scheduling
  • Spray system calls from multiple threads to create contention
  • Use NPU timers (NtSetTimerResolution) to increase scheduling granularity

Reliably Exploiting Races

  • Target races with large windows (e.g., file operation with network involved)
  • Use OpLock to pause execution at precise moment
  • Practice: aim for >90% reliability before considering exploitable

Fuzzing for Race Conditions

  • KAFL / WTF: can fuzz kernel paths with concurrent threads
  • krace (research): kernel race fuzzer using coverage + thread interleaving
  • Concurrence: record/replay-based race detection
  • Manual: instrument suspected race paths with ETW events, observe ordering

Exploit Relevance

Race conditions / TOCTOU are especially valuable because:

  1. They often affect high-privilege components (installers, system services, kernel)
  2. They don’t require memory corruption — logic bugs
  3. They survive memory safety mitigations entirely (no ASLR/DEP relevance)
  4. File system races (OpLock + junction) are a repeating pattern with new instances every year

James Forshaw (Project Zero) has documented the most systematic Windows TOCTOU toolkit — study his work extensively.


References

  • “Windows TOCTOU Exploitation” — James Forshaw (Project Zero)
  • “symboliclink-testing-tools” — James Forshaw, GitHub
  • “CVE-2019-0841” — SandboxEscaper analysis
  • “OpLock-based races” — James Forshaw blog
  • “Double-Fetch vulnerabilities in the Linux kernel” (cross-reference for methodology) — Wang et al.
  • “Race Condition Exploitation on Windows” — Alex Ionescu