Every CVE Search/ Get API key

CVE-2026-112941

filelock: SoftReadWriteLock follows a lock tree swapped in after its first acquire and writes lock records into directories of the user running the lock

3.3 LowFix available

filelock is a platform-independent file lock for Python. From 4.1.0 until 4.2.1, SoftReadWriteLock and AsyncSoftReadWriteLock cache a successful check of the <path>.rw lock tree and resolve its names again during later record operations, allowing another local user who can replace that tree after the first acquisition to redirect lock-record writes into directories writable by the lock user. This issue is fixed in version 4.2.1.

Attack profile

How easy it is to exploit

Attack vector
Local
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
Low
Availability
None

Exploit likelihood

0.13%Unchanged since Oct 21, 2026
90%50%10%1%

What each source reports

CVE List Score used 3.3

filelock: SoftReadWriteLock follows a lock tree swapped in after its first acquire and writes lock records into directories of the user running the lock

filelock is a platform-independent file lock for Python. From 4.1.0 until 4.2.1, SoftReadWriteLock and AsyncSoftReadWriteLock cache a successful check of the <path>.rw lock tree and resolve its names again during later record operations, allowing another local user who can replace that tree after the first acquisition to redirect lock-record writes into directories writable by the lock user. This issue is fixed in version 4.2.1.

Record
CVE-2026-112941
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-367
Updated
2026-11-02
EUVDEUVD-2026-105032 3.3

filelock is a platform-independent file lock for Python. From 4.1.0 until 4.2.1, SoftReadWriteLock and AsyncSoftReadWriteLock cache a successful check of the <path>.rw lock tree and resolve its names again during later record operations, allowing another local user who can replace that tree after the first acquisition to redirect lock-record writes into directories writable by the lock user. This issue is fixed in version 4.2.1.

Record
EUVD-2026-105032
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-wfhq-q4j2-c37m 3.3

filelock: SoftReadWriteLock follows a lock tree swapped in after its first acquire and writes lock records into directories of the user running the lock

SoftReadWriteLock (and AsyncSoftReadWriteLock, which wraps one) checks once per lock object, by name, that <path>.rw, <path>.rw/gen and <path>.rw/holders are real directories and not symbolic links (files that redirect to another path). It then keeps only a boolean. Every later record operation resolves the full path again, and O_NOFOLLOW (a flag that makes an open fail when the final name is a symbolic link) protects the last component only. Another local user (the other user below) who can write the directory holding the lock, or who created <path>.rw first in a sticky directory such as /tmp (the sticky bit is a directory flag that lets only a file's owner rename or remove it), can put a tree under that name whose gen or holders is a symbolic link into a directory of the user running the lock (the lock user below).

A long-running process of the lock user that has already passed the check then creates, renames over and deletes files there with the lock user's privileges, including in 0700 directories the other user cannot open. The names and bytes are filelock's own lock records, not chosen by the other user. The scanner's reproducer replaces .git/HEAD in the lock user's private repository so that git status fails. There is no race. Affected versions: filelock >= 4.1.0 and <= 4.2.0. Anthropic's OSS Scanner reported it in private as ANT-2026-WXXRI4M4 [high, CWE-367], titled "SoftReadWriteLock follows gen dir swapped for a symlink after first acquire".

Severity

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N, 3.3 (Low).

AV:L (local): the other user needs an account on the same host. AC:L (low attack complexity): the swap happens between two acquisitions, with no race to win. PR:L (low privileges): a local user with ordinary privileges is enough. UI:N (no user interaction): the lock user's process acts on its own. C:N (no confidentiality impact): the other user learns nothing. I:L (low integrity impact): the lock user's process replaces a file named HEAD, creates epoch and generation records, and deletes files whose names match the protocol's patterns, in any directory the lock user can write, with the lock user's privileges. The other user does not choose the bytes, but the files are gone and the chosen directory (a git repository) stops working. A:N (no availability impact): the lock itself keeps working and the lock user's process does not stall. The scanner rated it high; we scored the vector for a lock user with ordinary privileges.

Classification from the external review: conditional security. It is a cross-user replacement of a cached .rw tree that redirects later writes of the lock user through an intermediate symbolic link. It needs a planted tree in sticky /tmp or a writable parent without the sticky bit. Scoring note: we rate integrity low rather than high. The bytes written through the swapped tree are filelock's own records, not content the other user chose, so the lower reading of the CVSS integrity metric applies.

Scope and preconditions

  • Trust boundary: the other party is a different local account with write access to the lock's parent directory. Without the sticky bit (a 0777 scratch or spool directory, or a group-writable project or cache directory shared with that account's group) write access alone is enough. The other user renames the lock user's own 0700 <path>.rw aside and puts its tree in place. In a sticky parent such as /tmp the extra precondition is that it created <path>.rw (with real gen and holders directories, mode 0777) before the lock user's first acquire. prepare() accepts an existing tree whoever owns it, and the other user later replaces its own gen with a symbolic link. fs.protected_symlinks=1 (a Linux setting that refuses to follow another user's symbolic link in a world-writable sticky directory) does not intervene, because the link sits inside the other user's own non-sticky <path>.rw, not in the…
Record
GHSA-wfhq-q4j2-c37m
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-367
Updated
2026-11-02
NVD 3.3

filelock is a platform-independent file lock for Python. From 4.1.0 until 4.2.1, SoftReadWriteLock and AsyncSoftReadWriteLock cache a successful check of the <path>.rw lock tree and resolve its names again during later record operations, allowing another local user who can replace that tree after the first acquisition to redirect lock-record writes into directories writable by the lock user. This issue is fixed in version 4.2.1.

Record
CVE-2026-112941
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-367
Updated
2026-11-02
OSV 3.3

filelock: SoftReadWriteLock follows a lock tree swapped in after its first acquire and writes lock records into directories of the user running the lock

filelock is a platform-independent file lock for Python. From 4.1.0 until 4.2.1, SoftReadWriteLock and AsyncSoftReadWriteLock cache a successful check of the <path>.rw lock tree and resolve its names again during later record operations, allowing another local user who can replace that tree after the first acquisition to redirect lock-record writes into directories writable by the lock user. This issue is fixed in version 4.2.1.

Record
CVE-2026-112941
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-367
Updated
2026-11-02
OSVDEBIAN-CVE-2026-112941 3.3

filelock is a platform-independent file lock for Python. From 4.1.0 until 4.2.1, SoftReadWriteLock and AsyncSoftReadWriteLock cache a successful check of the <path>.rw lock tree and resolve its names again during later record operations, allowing another local user who can replace that tree after the first acquisition to redirect lock-record writes into directories writable by the lock user. This issue is fixed in version 4.2.1.

Record
DEBIAN-CVE-2026-112941
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Updated
2026-11-02
OSVGHSA-wfhq-q4j2-c37m 3.3

filelock: SoftReadWriteLock follows a lock tree swapped in after its first acquire and writes lock records into directories of the user running the lock

SoftReadWriteLock (and AsyncSoftReadWriteLock, which wraps one) checks once per lock object, by name, that <path>.rw, <path>.rw/gen and <path>.rw/holders are real directories and not symbolic links (files that redirect to another path). It then keeps only a boolean. Every later record operation resolves the full path again, and O_NOFOLLOW (a flag that makes an open fail when the final name is a symbolic link) protects the last component only. Another local user (the other user below) who can write the directory holding the lock, or who created <path>.rw first in a sticky directory such as /tmp (the sticky bit is a directory flag that lets only a file's owner rename or remove it), can put a tree under that name whose gen or holders is a symbolic link into a directory of the user running the lock (the lock user below).

A long-running process of the lock user that has already passed the check then creates, renames over and deletes files there with the lock user's privileges, including in 0700 directories the other user cannot open. The names and bytes are filelock's own lock records, not chosen by the other user. The scanner's reproducer replaces .git/HEAD in the lock user's private repository so that git status fails. There is no race. Affected versions: filelock >= 4.1.0 and <= 4.2.0. Anthropic's OSS Scanner reported it in private as ANT-2026-WXXRI4M4 [high, CWE-367], titled "SoftReadWriteLock follows gen dir swapped for a symlink after first acquire".

Severity

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N, 3.3 (Low).

AV:L (local): the other user needs an account on the same host. AC:L (low attack complexity): the swap happens between two acquisitions, with no race to win. PR:L (low privileges): a local user with ordinary privileges is enough. UI:N (no user interaction): the lock user's process acts on its own. C:N (no confidentiality impact): the other user learns nothing. I:L (low integrity impact): the lock user's process replaces a file named HEAD, creates epoch and generation records, and deletes files whose names match the protocol's patterns, in any directory the lock user can write, with the lock user's privileges. The other user does not choose the bytes, but the files are gone and the chosen directory (a git repository) stops working. A:N (no availability impact): the lock itself keeps working and the lock user's process does not stall. The scanner rated it high; we scored the vector for a lock user with ordinary privileges.

Classification from the external review: conditional security. It is a cross-user replacement of a cached .rw tree that redirects later writes of the lock user through an intermediate symbolic link. It needs a planted tree in sticky /tmp or a writable parent without the sticky bit. Scoring note: we rate integrity low rather than high. The bytes written through the swapped tree are filelock's own records, not content the other user chose, so the lower reading of the CVSS integrity metric applies.

Scope and preconditions

  • Trust boundary: the other party is a different local account with write access to the lock's parent directory. Without the sticky bit (a 0777 scratch or spool directory, or a group-writable project or cache directory shared with that account's group) write access alone is enough. The other user renames the lock user's own 0700 <path>.rw aside and puts its tree in place. In a sticky parent such as /tmp the extra precondition is that it created <path>.rw (with real gen and holders directories, mode 0777) before the lock user's first acquire. prepare() accepts an existing tree whoever owns it, and the other user later replaces its own gen with a symbolic link. fs.protected_symlinks=1 (a Linux setting that refuses to follow another user's symbolic link in a world-writable sticky directory) does not intervene, because the link sits inside the other user's own non-sticky <path>.rw, not in the…
Record
GHSA-wfhq-q4j2-c37m
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-367
Updated
2026-11-02
OSVUBUNTU-CVE-2026-112941 3.3

filelock is a platform-independent file lock for Python. From 4.1.0 until 4.2.1, SoftReadWriteLock and AsyncSoftReadWriteLock cache a successful check of the <path>.rw lock tree and resolve its names again during later record operations, allowing another local user who can replace that tree after the first acquisition to redirect lock-record writes into directories writable by the lock user. This issue is fixed in version 4.2.1.

Record
UBUNTU-CVE-2026-112941
CVSS 3.1
3.3 LowCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
filelock
PyPI
4.1.0 to 4.2.0
4.2.1
python-filelock
Debian:12
All versions, plus listed versions
3.12.2-13.12.3-13.12.4-13.13.1-13.13.3-1
Show 29 moreShow less
3.13.4-13.14.0-13.15.4-13.16.1-13.16.1-23.17.0-13.18.0-13.19.1-13.20.0-13.20.2-13.20.3-13.24.3-13.25.0-13.25.2-13.29.0-13.29.4-13.29.5-13.29.7-13.32.0-13.32.2-13.32.4-13.32.4-23.32.5-13.32.6-13.9.0-13.9.0-1+deb12u14.0.1-14.0.12-14.1.1-1
None known
python-filelock
Debian:13
All versions, plus listed versions
3.18.0-13.18.0-1+deb13u13.19.1-13.20.0-13.20.2-1
Show 17 moreShow less
3.20.3-13.24.3-13.25.0-13.25.2-13.29.0-13.29.4-13.29.5-13.29.7-13.32.0-13.32.2-13.32.4-13.32.4-23.32.5-13.32.6-14.0.1-14.0.12-14.1.1-1
None known
python-filelock
Debian:14
All versions, plus listed versions
3.18.0-13.19.1-13.20.0-13.20.2-13.20.3-1
Show 16 moreShow less
3.24.3-13.25.0-13.25.2-13.29.0-13.29.4-13.29.5-13.29.7-13.32.0-13.32.2-13.32.4-13.32.4-23.32.5-13.32.6-14.0.1-14.0.12-14.1.1-1
None known
filelock
PyPI
4.1.0 up to 4.2.1, plus listed versions
4.1.14.1.24.2.0
4.2.1
python-filelock
Ubuntu:Pro:18.04:LTS
All versions, plus listed versions
2.0.11-12.0.12-12.0.13-13.0.0-23.0.3-13.0.4-13.0.4-1ubuntu0.1~esm1
None known
python-filelock
Ubuntu:Pro:20.04:LTS
All versions, plus listed versions
3.0.12-13.0.12-23.0.12-2ubuntu0.1~esm1
None known
python-filelock
Ubuntu:Pro:22.04:LTS
All versions, plus listed versions
3.0.12-23.3.2-13.4.0-13.4.2-13.4.2-23.6.0-13.6.0-1ubuntu0.1~esm1
None known
python-filelock
Ubuntu:Pro:24.04:LTS
All versions, plus listed versions
3.12.2-13.12.4-13.13.1-13.13.1-1ubuntu0.1~esm1
None known
python-filelock
Ubuntu:26.10
All versions, plus listed versions
3.20.3-13.29.4-13.32.0-13.32.2-1
None known
python-filelock
Ubuntu:26.04:LTS
All versions, plus listed versions
3.18.0-13.20.0-13.20.2-13.20.3-1
None known

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-112941 is a low vulnerability (CVSS 3.3) in Tox-dev Filelock, published October 20, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.13%, the 2nd percentile. Fixed in filelock 4.2.1.

References

Show 5 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open