44//! filesystem. All methods in this module represent cross-platform filesystem 
55//! operations. Extra platform-specific functionality can be found in the 
66//! extension traits of `std::os::$platform`. 
7+ //! 
8+ //! # Time of Check to Time of Use (TOCTOU) 
9+ //! 
10+ //! Many filesystem operations are subject to a race condition known as "Time of Check to Time of Use" 
11+ //! (TOCTOU). This occurs when a program checks a condition (like file existence or permissions) 
12+ //! and then uses the result of that check to make a decision, but the condition may have changed 
13+ //! between the check and the use. 
14+ //! 
15+ //! For example, checking if a file exists and then creating it if it doesn't is vulnerable to 
16+ //! TOCTOU - another process could create the file between your check and creation attempt. 
17+ //! 
18+ //! Another example is with symbolic links: when removing a directory, if another process replaces 
19+ //! the directory with a symbolic link between the check and the removal operation, the removal 
20+ //! might affect the wrong location. This is why operations like [`remove_dir_all`] need to use 
21+ //! atomic operations to prevent such race conditions. 
22+ //! 
23+ //! To avoid TOCTOU issues: 
24+ //! - Be aware that metadata operations (like [`metadata`] or [`symlink_metadata`]) may be affected by 
25+ //! changes made by other processes. 
26+ //! - Use atomic operations when possible (like [`File::create_new`] instead of checking existence then creating). 
27+ //! - Keep file open for the duration of operations. 
728
829#![ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
930#![ deny( unsafe_op_in_unsafe_fn) ]  
@@ -548,13 +569,14 @@ impl File {
548569     /// non-exhaustive list of likely errors. 
549570     /// 
550571     /// This option is useful because it is atomic. Otherwise between checking whether a file 
551-      /// exists and creating a new one, the file may have been created by another process (a TOCTOU 
572+      /// exists and creating a new one, the file may have been created by another process (a [ TOCTOU]  
552573     /// race condition / attack). 
553574     /// 
554575     /// This can also be written using 
555576     /// `File::options().read(true).write(true).create_new(true).open(...)`. 
556577     /// 
557578     /// [`AlreadyExists`]: crate::io::ErrorKind::AlreadyExists 
579+      /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou 
558580     /// 
559581     /// # Examples 
560582     /// 
@@ -1610,7 +1632,7 @@ impl OpenOptions {
16101632     /// 
16111633     /// This option is useful because it is atomic. Otherwise between checking 
16121634     /// whether a file exists and creating a new one, the file may have been 
1613-      /// created by another process (a TOCTOU race condition / attack). 
1635+      /// created by another process (a [ TOCTOU]  race condition / attack). 
16141636     /// 
16151637     /// If `.create_new(true)` is set, [`.create()`] and [`.truncate()`] are 
16161638     /// ignored. 
@@ -1621,6 +1643,7 @@ impl OpenOptions {
16211643     /// [`.create()`]: OpenOptions::create 
16221644     /// [`.truncate()`]: OpenOptions::truncate 
16231645     /// [`AlreadyExists`]: io::ErrorKind::AlreadyExists 
1646+      /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou 
16241647     /// 
16251648     /// # Examples 
16261649     /// 
@@ -2954,17 +2977,17 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
29542977/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile`. 
29552978/// 
29562979/// ## Time-of-check to time-of-use (TOCTOU) race conditions 
2957- /// On a few platforms there is no way to remove a directory's contents without following symlinks 
2958- /// unless you perform a check and then operate on paths based on that directory. 
2959- /// This allows concurrently-running code to replace the directory with a symlink after the check, 
2960- /// causing a removal to instead operate on a path based on the symlink. This is a TOCTOU race. 
2961- /// By default, `fs::remove_dir_all` protects against a symlink TOCTOU race on all platforms 
2962- /// except the following. It should not be used in security-sensitive contexts on these platforms: 
2963- /// - Miri: Even when emulating targets where the underlying implementation will protect against 
2964- /// TOCTOU races, Miri will not do so. 
2965- /// - Redox OS: This function does not protect against TOCTOU races, as Redox does not implement 
2966- /// the required platform support to do so. 
2980+ /// See the [module-level TOCTOU explanation](self#time-of-check-to-time-of-use-toctou). 
2981+ /// 
2982+ /// On most platforms, `fs::remove_dir_all` protects against symlink TOCTOU races by default. 
2983+ /// However, on the following platforms, this protection is not provided and the function should 
2984+ /// not be used in security-sensitive contexts: 
2985+ /// - **Miri**: Even when emulating targets where the underlying implementation will protect against 
2986+ ///   TOCTOU races, Miri will not do so. 
2987+ /// - **Redox OS**: This function does not protect against TOCTOU races, as Redox does not implement 
2988+ ///   the required platform support to do so. 
29672989/// 
2990+ /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou 
29682991/// [changes]: io#platform-specific-behavior 
29692992/// 
29702993/// # Errors 
@@ -3238,7 +3261,7 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
32383261/// permission is denied on one of the parent directories. 
32393262/// 
32403263/// Note that while this avoids some pitfalls of the `exists()` method, it still can not 
3241- /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios 
3264+ /// prevent time-of-check to time-of-use ([ TOCTOU] ) bugs. You should only use it in scenarios 
32423265/// where those bugs are not an issue. 
32433266/// 
32443267/// # Examples 
@@ -3251,6 +3274,7 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder {
32513274/// ``` 
32523275/// 
32533276/// [`Path::exists`]: crate::path::Path::exists 
3277+ /// [TOCTOU]: self#time-of-check-to-time-of-use-toctou 
32543278#[ stable( feature = "fs_try_exists" ,  since = "1.81.0" ) ]  
32553279#[ inline]  
32563280pub  fn  exists < P :  AsRef < Path > > ( path :  P )  -> io:: Result < bool >  { 
0 commit comments