diff options
author | Florian Bruhin <git@the-compiler.org> | 2015-09-11 18:21:20 +0200 |
---|---|---|
committer | Florian Bruhin <git@the-compiler.org> | 2015-09-11 18:21:20 +0200 |
commit | 5fe420efb5b9fb0c6e1b28eb6c1287e72e37c519 (patch) | |
tree | 080c6d5e214d601817860b30b89542384c299187 | |
parent | 5d90e0ecd3047b2a011e08024b08a2fb13213dcf (diff) | |
download | qutebrowser-5fe420efb5b9fb0c6e1b28eb6c1287e72e37c519.tar.gz qutebrowser-5fe420efb5b9fb0c6e1b28eb6c1287e72e37c519.zip |
standarddir: Fix TOCTOU issue when creating paths.
Fixes #942.
-rw-r--r-- | qutebrowser/utils/standarddir.py | 7 | ||||
-rw-r--r-- | tests/unit/utils/test_standarddir.py | 20 |
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() |