summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <git@the-compiler.org>2015-09-11 18:21:20 +0200
committerFlorian Bruhin <git@the-compiler.org>2015-09-11 18:21:20 +0200
commit5fe420efb5b9fb0c6e1b28eb6c1287e72e37c519 (patch)
tree080c6d5e214d601817860b30b89542384c299187
parent5d90e0ecd3047b2a011e08024b08a2fb13213dcf (diff)
downloadqutebrowser-5fe420efb5b9fb0c6e1b28eb6c1287e72e37c519.tar.gz
qutebrowser-5fe420efb5b9fb0c6e1b28eb6c1287e72e37c519.zip
standarddir: Fix TOCTOU issue when creating paths.
Fixes #942.
-rw-r--r--qutebrowser/utils/standarddir.py7
-rw-r--r--tests/unit/utils/test_standarddir.py20
2 files changed, 25 insertions, 2 deletions
diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py
index fe0c928e1..df3a7e3f0 100644
--- a/qutebrowser/utils/standarddir.py
+++ b/qutebrowser/utils/standarddir.py
@@ -163,8 +163,11 @@ def _get(typ):
# non-existant an attempt should be made to create it with permission
# 0700. If the destination directory exists already the permissions
# should not be changed.
- if path is not None and not os.path.exists(path):
- os.makedirs(path, 0o700)
+ if path is not None:
+ try:
+ os.makedirs(path, 0o700)
+ except FileExistsError:
+ pass
return path
diff --git a/tests/unit/utils/test_standarddir.py b/tests/unit/utils/test_standarddir.py
index 1fe9bb67d..1302034e1 100644
--- a/tests/unit/utils/test_standarddir.py
+++ b/tests/unit/utils/test_standarddir.py
@@ -316,3 +316,23 @@ class TestCreatingDir:
if os.name == 'posix':
assert basedir.stat().mode & 0o777 == 0o700
+
+ @pytest.mark.parametrize('typ', DIR_TYPES)
+ def test_exists_race_condition(self, mocker, tmpdir, typ):
+ """Make sure there can't be a TOCTOU issue when creating the file.
+
+ See https://github.com/The-Compiler/qutebrowser/issues/942.
+ """
+ (tmpdir / typ).ensure(dir=True)
+
+ m = mocker.patch('qutebrowser.utils.standarddir.os')
+ m.makedirs = os.makedirs
+ m.sep = os.sep
+ m.path.join = os.path.join
+ m.path.exists.return_value = False
+
+ args = types.SimpleNamespace(basedir=str(tmpdir))
+ standarddir.init(args)
+
+ func = getattr(standarddir, typ)
+ func()