From c07f9db7726babc801ea3bd6f7c0f09d92a48bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Fri, 9 Jan 2026 09:53:50 -0800 Subject: [PATCH] Fix TOCTOU symlink vulnerability in SoftFileLock (#465) CVE: CVE-2026-22701 Upstream-Status: Backport [https://github.com/tox-dev/filelock/commit/41b42dd2c72aecf7da83dbda5903b8087dddc4d5] Backport Changes: - Omitted docs/index.rst because the filelock 3.13.4 source archive does not contain the upstream documentation tree. The omission does not affect the SoftFileLock security fix. Co-authored-by: Claude (cherry picked from commit 41b42dd2c72aecf7da83dbda5903b8087dddc4d5) Signed-off-by: Darsh Kelaiya --- src/filelock/_soft.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/filelock/_soft.py b/src/filelock/_soft.py index 28c67f7..93709c5 100644 --- a/src/filelock/_soft.py +++ b/src/filelock/_soft.py @@ -16,13 +16,15 @@ class SoftFileLock(BaseFileLock): def _acquire(self) -> None: raise_on_not_writable_file(self.lock_file) ensure_directory_exists(self.lock_file) - # first check for exists and read-only mode as the open will mask this case as EEXIST flags = ( os.O_WRONLY # open for writing only | os.O_CREAT | os.O_EXCL # together with above raise EEXIST if the file specified by filename exists | os.O_TRUNC # truncate the file to zero byte ) + o_nofollow = getattr(os, "O_NOFOLLOW", None) + if o_nofollow is not None: + flags |= o_nofollow try: file_handler = os.open(self.lock_file, flags, self._context.mode) except OSError as exception: # re-raise unless expected exception -- 2.44.4