From 851a776bf5a5f83846caced242c8b54a6e4aef24 Mon Sep 17 00:00:00 2001 From: Sean Gillespie Date: Mon, 19 Nov 2018 15:48:56 -0800 Subject: [PATCH 1/2] Fix a TOCTOU issue in mkdir_p When running multiple pipenv processes simultaneously, they may both attempt to use 'mkdir_p' at the same time, which can cause one of the pipenv processes to crash when it tries to create a directory that already exists. Instead of crashing outright, this commit instead opts to continue onward if the 'os.mkdir' call failed with EEXIST, which is fine since we're trying to create the directory anyway after ascertaining that it didn't exist before. --- pipenv/utils.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 22837d26..84a4c105 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -832,8 +832,18 @@ def mkdir_p(newdir): if head and not os.path.isdir(head): mkdir_p(head) if tail: - os.mkdir(newdir) + # Even though we've checked that the directory doesn't exist above, it might exist + # now if some other process has created it between now and the time we checked it. + try: + os.mkdir(newdir) + except OSError as exn: + # If we failed because the directory does exist, that's not a problem - + # that's what we were trying to do anyway. Only re-raise the exception + # if we failed for some other reason. + if exn.errno != errno.EEXIST: + raise + def is_required_version(version, specified_version): """Check to see if there's a hard requirement for version From 537e7b4779a5715a12cfc9de3e981f559932f98e Mon Sep 17 00:00:00 2001 From: Sean Gillespie Date: Mon, 19 Nov 2018 16:04:52 -0800 Subject: [PATCH 2/2] Add 3257.bugfix.rst in news --- news/3257.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/3257.bugfix.rst diff --git a/news/3257.bugfix.rst b/news/3257.bugfix.rst new file mode 100644 index 00000000..c816c93a --- /dev/null +++ b/news/3257.bugfix.rst @@ -0,0 +1 @@ +Fixed an issue where pipenv could crash when multiple pipenv processes attempted to create the same directory.