gitpython-developers / gitdb

IO of git-style object databases
http://gitdb.readthedocs.org
Other
212 stars 65 forks source link

Race condition writing objects in LooseObjectDB #85

Closed lordmauve closed 10 months ago

lordmauve commented 1 year ago

There's a TOCTTOU in LooseObjectDB when storing a new object, that causes storing an object to fail with FileExistsError:

   File "patch_tree.py", line 132, in write_tree
     return self.db.store(istream).binsha
   File ".venv/lib/python3.9/gitdb/db/git.py", line 77, in store
     return self._loose_db.store(istream)
   File ".venv/lib/python3.9/gitdb/db/loose.py", line 226, in store
     mkdir(obj_dir)
FileExistsError: [Errno 17] File exists: '/tmp/tmp.flUcclypOQ/objects/a0'

The problem code is

            if not isdir(obj_dir):
                mkdir(obj_dir)

and what is happening is

  1. isdir() returns False because the directory does not exist at that moment
  2. The directory is created in another thread
  3. mkdir() fails with FileExistsError

This can be avoided by using an EAFP pattern, e.g.

with contextlib.suppress(FileExistsError):
    mkdir(obj_dir)
Byron commented 1 year ago

Thanks for reporting and for providing a suggestion for a fix. A PR is definitely welcome.