forked from pool/python-filelock
Compare commits
12 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| f4c5858363 | |||
| c4a8737406 | |||
| adc4aa74d9 | |||
| f8d1910013 | |||
| d2053e1b98 | |||
| 0a519cc0ee | |||
| 413069b4bb | |||
| 5b9b589384 | |||
| 40005fbf11 | |||
| 8abd4711f0 | |||
| aa4be953b0 | |||
| 76165c8c12 |
14
CVE-2025-68146.patch
Normal file
14
CVE-2025-68146.patch
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Index: filelock-3.18.0/src/filelock/_unix.py
|
||||||
|
===================================================================
|
||||||
|
--- filelock-3.18.0.orig/src/filelock/_unix.py
|
||||||
|
+++ filelock-3.18.0/src/filelock/_unix.py
|
||||||
|
@@ -39,6 +39,9 @@ else: # pragma: win32 no cover
|
||||||
|
def _acquire(self) -> None:
|
||||||
|
ensure_directory_exists(self.lock_file)
|
||||||
|
open_flags = os.O_RDWR | os.O_TRUNC
|
||||||
|
+ o_nofollow = getattr(os, "O_NOFOLLOW", None)
|
||||||
|
+ if o_nofollow is not None:
|
||||||
|
+ open_flags |= o_nofollow
|
||||||
|
if not Path(self.lock_file).exists():
|
||||||
|
open_flags |= os.O_CREAT
|
||||||
|
fd = os.open(self.lock_file, open_flags, self._context.mode)
|
||||||
63
CVE-2026-22701.patch
Normal file
63
CVE-2026-22701.patch
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
From 255ed068bc85d1ef406e50a135e1459170dd1bf0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= <bgabor8@bloomberg.net>
|
||||||
|
Date: Fri, 9 Jan 2026 09:23:12 -0800
|
||||||
|
Subject: [PATCH] Fix TOCTOU symlink vulnerability in SoftFileLock
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Add O_NOFOLLOW flag to prevent symlink attacks. The vulnerability existed
|
||||||
|
between the permission check and the actual file creation, allowing an
|
||||||
|
attacker to create a symlink at the lock path.
|
||||||
|
|
||||||
|
How the fix prevents the attack:
|
||||||
|
1. raise_on_not_writable_file() validates permissions (doesn't follow symlinks)
|
||||||
|
2. RACE WINDOW: attacker creates symlink to target file
|
||||||
|
3. os.open() with O_NOFOLLOW refuses to follow the symlink
|
||||||
|
4. Attack is prevented - the symlink won't help attacker
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- Add conditional O_NOFOLLOW flag (like UnixFileLock does in commit 5088854)
|
||||||
|
- Gracefully degrade on platforms without O_NOFOLLOW (e.g., GraalPy)
|
||||||
|
- No behavioral changes to existing code
|
||||||
|
|
||||||
|
Security improvement:
|
||||||
|
- Platforms with O_NOFOLLOW: ✅ Symlink attacks completely prevented
|
||||||
|
- Platforms without O_NOFOLLOW: ⚠️ TOCTOU window remains but documented
|
||||||
|
|
||||||
|
The pre-check (raise_on_not_writable_file) is safe from TOCTOU itself because
|
||||||
|
it only reads metadata. The attack only works if a symlink is followed by a
|
||||||
|
write operation. By preventing symlink following in os.open() with O_NOFOLLOW,
|
||||||
|
the attack is blocked even if the symlink is created during the race window.
|
||||||
|
|
||||||
|
Reported by George Tsigourakos (@tsigouris007)
|
||||||
|
|
||||||
|
🤖 Generated with Claude Code
|
||||||
|
|
||||||
|
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||||
|
---
|
||||||
|
docs/index.rst | 16 ++++++++++++++++
|
||||||
|
src/filelock/_soft.py | 4 +++-
|
||||||
|
2 files changed, 19 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/filelock/_soft.py b/src/filelock/_soft.py
|
||||||
|
index 28c67f74..93709c5c 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
|
||||||
3
_multibuild
Normal file
3
_multibuild
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<multibuild>
|
||||||
|
<package>test</package>
|
||||||
|
</multibuild>
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:58a2549afdf9e02e10720eaa4d4470f56386d7a6f72edd7d0596337af8ed7ad8
|
|
||||||
size 17564
|
|
||||||
BIN
filelock-3.18.0.tar.gz
LFS
Normal file
BIN
filelock-3.18.0.tar.gz
LFS
Normal file
Binary file not shown.
@@ -1,3 +1,49 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 14 13:09:53 UTC 2026 - Nico Krapp <nico.krapp@suse.com>
|
||||||
|
|
||||||
|
- Add CVE-2026-22701.patch to fix CVE-2026-22701 (bsc#1256457)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 7 09:12:08 UTC 2026 - Nico Krapp <nico.krapp@suse.com>
|
||||||
|
|
||||||
|
- Add CVE-2025-68146.patch to fix CVE-2025-68146 (bsc#1255244)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Mar 19 07:44:21 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
|
||||||
|
|
||||||
|
- Update to 3.18.0
|
||||||
|
* Indicate that locks are exclusive/write locks
|
||||||
|
* Support fcntl check on Emscripten
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Jan 30 11:22:48 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
|
||||||
|
|
||||||
|
- Update to 3.17.0
|
||||||
|
* Drop support for Python 3.8
|
||||||
|
* Update README.md
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Oct 9 07:27:30 UTC 2024 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
|
||||||
|
|
||||||
|
- Update to 3.16.1
|
||||||
|
* CI improvements
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Sun Sep 8 15:56:37 UTC 2024 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
- update to 3.16.0:
|
||||||
|
* Test Python 3.13
|
||||||
|
* Add 3.13 to CI
|
||||||
|
- update to 3.15.4:
|
||||||
|
* Pass `file_lock` as positional argument
|
||||||
|
- update to 3.15.3:
|
||||||
|
* Add test for virtualenv stability
|
||||||
|
* Fix `TypeError: _CountedFileLock.__init__() got an unexpected
|
||||||
|
keyword argument 'timeout'`
|
||||||
|
- update to 3.15.2:
|
||||||
|
* Use a metaclass to implement the singleton pattern
|
||||||
|
- split into test multibuild to avoid cycle over virtualenv
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Mon Jun 17 06:00:15 UTC 2024 - Dirk Müller <dmueller@suse.com>
|
Mon Jun 17 06:00:15 UTC 2024 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package python-filelock
|
# spec file for package python-filelock
|
||||||
#
|
#
|
||||||
# Copyright (c) 2024 SUSE LLC
|
# Copyright (c) 2025 SUSE LLC
|
||||||
# Copyright (c) 2018 Matthias Fehring <buschmann23@opensuse.org>
|
# Copyright (c) 2018 Matthias Fehring <buschmann23@opensuse.org>
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
@@ -17,22 +17,37 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
%global flavor @BUILD_FLAVOR@%{nil}
|
||||||
|
%if "%{flavor}" == "test"
|
||||||
|
%define pkg_suffix -test
|
||||||
|
%bcond_without test
|
||||||
|
%else
|
||||||
|
%define pkg_suffix %{nil}
|
||||||
|
%bcond_with test
|
||||||
|
%endif
|
||||||
%{?sle15_python_module_pythons}
|
%{?sle15_python_module_pythons}
|
||||||
Name: python-filelock
|
Name: python-filelock%{?pkg_suffix}
|
||||||
Version: 3.15.1
|
Version: 3.18.0
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: Platform Independent File Lock in Python
|
Summary: Platform Independent File Lock in Python
|
||||||
License: Unlicense
|
License: Unlicense
|
||||||
URL: https://github.com/tox-dev/py-filelock
|
URL: https://github.com/tox-dev/py-filelock
|
||||||
Source: https://files.pythonhosted.org/packages/source/f/filelock/filelock-%{version}.tar.gz
|
Source: https://files.pythonhosted.org/packages/source/f/filelock/filelock-%{version}.tar.gz
|
||||||
|
# PATCH-FIX-UPSTREAM CVE-2025-68146.patch bsc#1255244 (gh#tox-dev/filelock/pulls/461, gh#tox-dev/filelock/pulls/463)
|
||||||
|
Patch0: CVE-2025-68146.patch
|
||||||
|
# PATCH-FIX-UPSTREAM CVE-2026-22701.patch bsc#1256457 (gh#tox-dev/filelock/pulls/465)
|
||||||
|
Patch1: CVE-2026-22701.patch
|
||||||
BuildRequires: %{python_module asyncio}
|
BuildRequires: %{python_module asyncio}
|
||||||
BuildRequires: %{python_module hatch_vcs}
|
BuildRequires: %{python_module hatch_vcs}
|
||||||
BuildRequires: %{python_module hatchling}
|
BuildRequires: %{python_module hatchling}
|
||||||
BuildRequires: %{python_module pip}
|
BuildRequires: %{python_module pip}
|
||||||
|
BuildRequires: %{python_module wheel}
|
||||||
|
%if %{with test}
|
||||||
BuildRequires: %{python_module pytest-asyncio}
|
BuildRequires: %{python_module pytest-asyncio}
|
||||||
BuildRequires: %{python_module pytest-mock}
|
BuildRequires: %{python_module pytest-mock}
|
||||||
BuildRequires: %{python_module pytest}
|
BuildRequires: %{python_module pytest}
|
||||||
BuildRequires: %{python_module wheel}
|
BuildRequires: %{python_module virtualenv}
|
||||||
|
%endif
|
||||||
BuildRequires: fdupes
|
BuildRequires: fdupes
|
||||||
BuildRequires: python-rpm-macros
|
BuildRequires: python-rpm-macros
|
||||||
%if 0%{?python_version_nodots} < 311
|
%if 0%{?python_version_nodots} < 311
|
||||||
@@ -48,22 +63,25 @@ independent file lock in Python, which provides a simple way of
|
|||||||
inter-process communication.
|
inter-process communication.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -n filelock-%{version}
|
%autosetup -p1 -n filelock-%{version}
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%pyproject_wheel
|
%pyproject_wheel
|
||||||
|
|
||||||
|
%if !%{with test}
|
||||||
%install
|
%install
|
||||||
%pyproject_install
|
%pyproject_install
|
||||||
%python_expand %fdupes %{buildroot}/%{$python_sitelib}
|
%python_expand %fdupes %{buildroot}/%{$python_sitelib}
|
||||||
|
|
||||||
%check
|
|
||||||
%pytest -rs
|
|
||||||
|
|
||||||
%files %{python_files}
|
%files %{python_files}
|
||||||
%doc README.md
|
%doc README.md
|
||||||
%license LICENSE
|
%license LICENSE
|
||||||
%{python_sitelib}/filelock
|
%{python_sitelib}/filelock
|
||||||
%{python_sitelib}/filelock-%{version}*-info
|
%{python_sitelib}/filelock-%{version}*-info
|
||||||
|
%else
|
||||||
|
|
||||||
|
%check
|
||||||
|
%pytest -rs
|
||||||
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
|||||||
Reference in New Issue
Block a user