fix: TOCTOU race when creating directories#34
Merged
gulrak merged 1 commit intogulrak:masterfrom Nov 6, 2019
jeanguyomarch:toctou-race
Merged
fix: TOCTOU race when creating directories#34gulrak merged 1 commit intogulrak:masterfrom jeanguyomarch:toctou-race
gulrak merged 1 commit intogulrak:masterfrom
jeanguyomarch:toctou-race
Conversation
When create_directories() is called to create a chain of directories, path components are created one by one. For each path component, ghc checks if the directory exists. If not it attempts to create it. In case of failure to create this directory, the function fails. This behavior exhibits a TOCTOU (Time Of Check/Time Of Use) race when different threads of execution (e.g. different processes) attempt to create the same paths (or paths that contain a common hierarchy). The following sequence of events between threads T1 and T2 illustrates the issue: T1: checks path P exists: no. Will attempt to create P... T2: checks path P exists: no. Will attempt to create P... T1: creates P, no error T2: fails to create P: raises an error It is not desirable for create_directories() to fail in this case. This commit mirrors the GNU libstdc++ implementation of the c++ filesystem library: if the creation of a directory fails, we will inspect the path that should have been created as a directory. If it is indeed a directory (another thread of execution created it for us), the error is now reset and the function continues to iterate to the next path component.
Owner
|
Thank you for the PR! Yes, this is a better behaviour. |
Owner
|
Hi @jeanguyomarch! There is interest to move to the more liberal MIT license. To allow this to happen, I would like to ask you as a contributor, to agree to this re-licensing with a reply to issue #47 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When create_directories() is called to create a chain of directories,
path components are created one by one. For each path component, ghc
checks if the directory exists. If not it attempts to create it. In
case of failure to create this directory, the function fails.
This behavior exhibits a TOCTOU (Time Of Check/Time Of Use) race when
different threads of execution (e.g. different processes) attempt to
create the same paths (or paths that contain a common hierarchy).
The following sequence of events between threads T1 and T2 illustrates
the issue:
T1: checks path P exists: no. Will attempt to create P...
T2: checks path P exists: no. Will attempt to create P...
T1: creates P, no error
T2: fails to create P: raises an error
It is not desirable for create_directories() to fail in this case. This
commit mirrors the GNU libstdc++ implementation of the c++ filesystem
library: if the creation of a directory fails, we will inspect the path
that should have been created as a directory. If it is indeed a
directory (another thread of execution created it for us), the error is
now reset and the function continues to iterate to the next path
component.