mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-20 18:59:07 -05:00
fix: claim a partial only under its own name
Opening and locking a partial download are two steps. Between them another run could finish, rename the same file into place and release its lock. The second run then locked the installed BIOS, read its full size as a finished partial and truncated it to download again. After the lock the partial's name must still point at the locked file, or the run downloads into a private copy.
This commit is contained in:
1 parent
d1ff233990
commit
aea67e998f
4 files changed
+38
-2
No files matched your search
@@ -145,6 +145,31 @@ class TwoRunsOneFolder(unittest.TestCase):
|
||||
self.assertIsNotNone(install._claim_partial(part))
|
||||
|
||||
|
||||
class APartialRenamedBeforeTheLock(unittest.TestCase):
|
||||
"""Open and lock are two steps. The run holding the partial could finish
|
||||
in between, rename it into place and release it: the second run then
|
||||
locked the installed BIOS, took it for a finished partial and truncated it."""
|
||||
|
||||
@unittest.skipIf(os.name == "nt", "flock semantics")
|
||||
def test_the_installed_file_is_not_claimed(self):
|
||||
import fcntl
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
part = Path(tmp) / ".big.bin.part"
|
||||
final = Path(tmp) / "big.bin"
|
||||
part.write_bytes(PAYLOAD)
|
||||
real_flock = fcntl.flock
|
||||
|
||||
def finish_first(fd, op):
|
||||
os.replace(part, final)
|
||||
return real_flock(fd, op)
|
||||
|
||||
with mock.patch.object(fcntl, "flock", finish_first):
|
||||
claimed = install._claim_partial(part)
|
||||
self.assertIsNone(claimed)
|
||||
self.assertEqual(final.read_bytes(), PAYLOAD)
|
||||
|
||||
|
||||
class InstalledFileModes(unittest.TestCase):
|
||||
"""A file came out 0600, the mode of the temporary it was written to: run
|
||||
with sudo for a root-owned BIOS folder, the emulator's own user could not
|
||||
|
||||
Reference in new issue
Block a user