From 7f7c415d03e6ec431a65a6f5625026761ab9f913 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 1 May 2025 18:23:07 -0700 Subject: [PATCH] library: explain TOCTOU races in `fs::remove_dir_all` In the previous description it said there was a TOCTOU race but did not explain exactly what the problem was. I sat down with the CVE, reviewed its text, and created this explanation. This context should hopefully help people understand the actual risk as-such. Incidentally, it also fixes the capitalization on the name of Redox OS. --- library/std/src/fs.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 8ed5800e9d06b..711efc7d011c1 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2915,17 +2915,28 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// # Platform-specific behavior /// -/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions -/// on Unix (except for REDOX) and the `CreateFileW`, `GetFileInformationByHandleEx`, -/// `SetFileInformationByHandle`, and `NtCreateFile` functions on Windows. Note that, this -/// [may change in the future][changes]. +/// These implementation details [may change in the future][changes]. +/// +/// - "Unix-like": By default, this function currently corresponds to +/// `openat`, `fdopendir`, `unlinkat` and `lstat` +/// on Unix-family platforms, except where noted otherwise. +/// - "Windows": This function currently corresponds to `CreateFileW`, +/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile`. +/// +/// ## Time-of-check to time-of-use (TOCTOU) race conditions +/// On a few platforms there is no way to remove a directory's contents without following symlinks +/// unless you perform a check and then operate on paths based on that directory. +/// This allows concurrently-running code to replace the directory with a symlink after the check, +/// causing a removal to instead operate on a path based on the symlink. This is a TOCTOU race. +/// By default, `fs::remove_dir_all` protects against a symlink TOCTOU race on all platforms +/// except the following. It should not be used in security-sensitive contexts on these platforms: +/// - Miri: Even when emulating targets where the underlying implementation will protect against +/// TOCTOU races, Miri will not do so. +/// - Redox OS: This function does not protect against TOCTOU races, as Redox does not implement +/// the required platform support to do so. /// /// [changes]: io#platform-specific-behavior /// -/// On REDOX, as well as when running in Miri for any target, this function is not protected against -/// time-of-check to time-of-use (TOCTOU) race conditions, and should not be used in -/// security-sensitive code on those platforms. All other platforms are protected. -/// /// # Errors /// /// See [`fs::remove_file`] and [`fs::remove_dir`].