# TOCTOU check-then-use swap

A name or handle validated, then re-resolved or reopened before use, letting content swap in between

_Area: Memory corruption and native code. Seen in 6 disclosed reports; 4 confirmed bounties, median $5,500, range $2,480-$30,500; latest 2025-07-03. Updated 2026-10-23._

## How it works
A program validates something about a file, path, or object — its type, signature, ownership, or contents — and then, as a separate step, resolves or opens that same name again to use it. The check and the use are two different lookups. Between them the name can be made to point at different content: a symlink swapped in, a file replaced over a network share, a directory entry exchanged. The validator approved one object; the consumer got another. The broken assumption is that a pathname identifies a stable object across time. Holding one open handle defeats the race only if the consumer actually uses that handle — the kernel binds a handle to the object, not the name. A handle that is closed and re-derived by path reopens the race.

## Where it shows up
- `stat()`/`lstat()`/`access()` immediately followed by `fopen()`/`open()` on the same path [E3](https://bugbountylibrary.com/r/h1%3A2078571.md).
- Temp-file-then-`rename()` writes where the destination path comes from an environment variable; `rename()` resolves old and new paths separately [E1](https://bugbountylibrary.com/r/blog%3Agergelykalman-com-lateralus-cve-2023-32407-a-macos-tcc-bypass-html.md).
- Signature verification followed by close and reopen-by-path (`LoadLibrary`) [E2](https://bugbountylibrary.com/r/blog%3Aexploits-forsale-themebleed.md).
- SUID binary validating a sibling helper by path, then exec'ing it without holding a lock [E8](https://bugbountylibrary.com/r/h1%3A1251464.md).
- Install/update flows that place a binary at a predictable path, then execute it as root without synchronization [E7](https://bugbountylibrary.com/r/h1%3A2261577.md).
- Protection applied in a process-creation callback rather than an object callback, leaving a window where a full-access handle is granted before protection applies [E5](https://bugbountylibrary.com/r/h1%3A966494.md).

## How to review
Find every place a property is established and then the object is re-obtained. The invariant: the object validated is the same object used, with no re-resolution of a name in between, and the consumer reads/executes through the validated handle. Audit recipe: grep for `stat`/`lstat`/`access` near `fopen`/`open`/`LoadLibrary` on the same variable; grep for `rename(` where the destination is attacker-influenced; grep for signature-check functions followed by a close. Safe: open once and validate/use through that one handle — `openat2` with `RESOLVE_NOFOLLOW`/`RESOLVE_BENEATH`, `O_EXCL`/`O_NOFOLLOW` for writes, then `fstat` the descriptor and read/execute from it; or copy to a private location and verify the copy. Unsafe: any close-then-reopen, any second path lookup, any reliance on filesystem permissions as a substitute for holding the handle. For protection logic, confirm the check runs in the earliest callback (object callback, not process callback) [E5](https://bugbountylibrary.com/r/h1%3A966494.md).

## Variants seen
- `stat` type check then separate `fopen` on the same name [E3](https://bugbountylibrary.com/r/h1%3A2078571.md).
- Env-var-controlled path written via temp-file-then-`rename()` [E1](https://bugbountylibrary.com/r/blog%3Agergelykalman-com-lateralus-cve-2023-32407-a-macos-tcc-bypass-html.md).
- Signature verified, then closed and reopened by path [E2](https://bugbountylibrary.com/r/blog%3Aexploits-forsale-themebleed.md).
- SUID binary validates sibling helper, then exec's it unlocked [E8](https://bugbountylibrary.com/r/h1%3A1251464.md).
- Binary placed then executed as root with a swap window [E7](https://bugbountylibrary.com/r/h1%3A2261577.md).
- Handle granted before protection callback fires [E5](https://bugbountylibrary.com/r/h1%3A966494.md).

## Impact and severity
Ranged from cookie leakage or protected-file overwrite [E3](https://bugbountylibrary.com/r/h1%3A2078571.md) and TCC bypass via arbitrary file write [E1](https://bugbountylibrary.com/r/blog%3Agergelykalman-com-lateralus-cve-2023-32407-a-macos-tcc-bypass-html.md) to arbitrary code execution via theme loader [E2](https://bugbountylibrary.com/r/blog%3Aexploits-forsale-themebleed.md), root code execution [E7](https://bugbountylibrary.com/r/h1%3A2261577.md)[E8](https://bugbountylibrary.com/r/h1%3A1251464.md), and access-mask bypass [E5](https://bugbountylibrary.com/r/h1%3A966494.md). Severity rises when the swapped object is later trusted at higher privilege and when the swap can be staged over a share.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Agergelykalman-com-lateralus-cve-2023-32407-a-macos-tcc-bypass-html.md
- E2: https://bugbountylibrary.com/r/blog%3Aexploits-forsale-themebleed.md
- E3: https://bugbountylibrary.com/r/h1%3A2078571.md
- E4: https://bugbountylibrary.com/r/blog%3Agithub-com-kkent030315-van1338.md
- E5: https://bugbountylibrary.com/r/h1%3A966494.md
- E6: https://bugbountylibrary.com/r/ghsa%3AGHSA-g842-9rc4-69pw.md
- E7: https://bugbountylibrary.com/r/h1%3A2261577.md
- E8: https://bugbountylibrary.com/r/h1%3A1251464.md
