PHP2Shell: Read our blog on the critical RCE vulnerabilities affecting 70% of the Internet
Vulnerability DatabaseCVE-2026-112939

CVE-2026-112939: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-112939 is a lock-marker forgery vulnerability in the filelock Python library (tox-dev/filelock) affecting versions 3.22.0 through 4.2.0. The flaw allows a local attacker who can write — but not remove — a SoftFileLock marker file to overwrite the live holder's process identifier (PID) record with a non-existent PID, causing a same-user or root contender to judge the lock stale, remove the live marker, and acquire the lock alongside the original holder. This breaks mutual exclusion without signaling an error to either process. The vulnerability was reported on October 15, 2026 by Anthropic's OSS Scanner (finding ANT-2026-W1H9NXUH), disclosed via GitHub Security Advisory GHSA-rfpc-qcw5-3pc4 on October 17, 2026, and patched in version 4.2.1 released the same day. It carries a CVSS v3.1 base score of 4.7 (Medium) (GitHub Advisory, Red Hat CVE).

Technical details

The root cause is classified as CWE-345 (Insufficient Verification of Data Authenticity) and CWE-807 (Reliance on Untrusted Inputs in a Security Decision). The SoftFileLock implementation introduced stale-lock detection in version 3.22.0 (commit e35c3af) via _try_break_stale_lock, which calls owner_is_stale() to determine if the recorded PID is dead — but it never verifies that the record was written by the file's owner (st_uid is not checked). When a marker is created with group or other write bits (e.g., mode=0o666 via explicit fchmod since 4.1.0, or under a permissive umask such as 002/000 in a shared directory), a local attacker can open the marker with O_WRONLY|O_TRUNC (without O_CREAT, bypassing fs.protected_regular) and write a forged record containing PID 2147483647 (an impossible PID on Linux) and the original holder's hostname. The next contender running as the holder's account or root then calls owner_is_stale(), which returns True for the forged dead PID, renames the marker to a .break.* name, unlinks it, and acquires the lock — admitting two processes into the critical section simultaneously with no error raised to either (GitHub Advisory, Fix PR #836).

Impact

Successful exploitation breaks mutual exclusion, allowing two processes to simultaneously execute a critical section protected by the lock. The integrity impact is high: any shared resource the lock protects — such as a cache directory, install directory, or state file — becomes subject to concurrent writes, potentially resulting in data corruption, inconsistent state, or silent data loss. There is no confidentiality or availability impact; the attacker gains no additional access beyond the ability to corrupt the shared resource, and the original holder receives no error signal. The affected lock classes include SoftFileLock, MarkerSoftFileLock, SoftFileLease, their async variants, and any FileLock that falls back to soft-lock mode on ENOSYS (GitHub Advisory).

Exploitability

A proof-of-concept (PoC) exploit consisting of three runnable Python scripts (repro, worker.py, rewrite_marker.py) is publicly available in the GitHub Security Advisory and was confirmed to reproduce the bug on filelock 4.2.0 and pass cleanly on 4.2.1. The exploit is not automatable (requires local account access and specific file permission preconditions) and is not chainable to further privilege escalation. There is no evidence of in-the-wild exploitation at this time. The EPSS score is 0.0, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. NVD SSVC classifies exploitation status as "poc" with partial technical impact (GitHub Advisory, Feedly).

Exploitation steps

  1. Identify a vulnerable target: Confirm the target system runs filelock version 3.22.0–4.2.0 and that a SoftFileLock (or variant) is in use with a marker file that has group or other write bits set (e.g., mode=0o666, or default mode under umask 002/000 in a shared directory).
  2. Confirm write access to the marker: As the attacker account, verify the marker file (e.g., cache.lock) is writable but not removable — for example, it resides in a sticky directory (chmod 1777) owned by another user.
  3. Confirm the marker cannot be deleted: Run rm -f <lock_path> as the attacker; expect Operation not permitted due to the sticky bit, confirming the forgery path is needed.
  4. Read the holder's hostname from the marker: Open the marker file and extract the second line (the holder's hostname), which owner_is_stale() requires to match for the stale check to proceed.
  5. Overwrite the marker with a forged dead PID: Execute rewrite_marker.py as the attacker: open the marker with os.open(lock_path, os.O_WRONLY | os.O_TRUNC) (no O_CREAT) and write 2147483647\n<holder_host>\n — PID 2147483647 cannot exist on Linux (pid_max ≤ 2²²).
  6. Trigger the contender: A second process running as the holder's account (or root) attempts to acquire the same lock. _try_break_stale_lock reads the forged record, owner_is_stale() returns True for the non-existent PID, and the contender renames then unlinks the marker.
  7. Second process enters the critical section: On its next poll, the contender's O_CREAT|O_EXCL create succeeds and it acquires the lock — running concurrently with the original holder, which receives no error (GitHub Advisory).

Indicators of compromise

  • File System: Marker files (e.g., *.lock) in shared/sticky directories with permissions -rw-rw-rw- (0o666) or -rw-rw-r-- (0o664) owned by one user but writable by others; unexpected truncation or modification of a lock marker file while the owning process is still running; presence of .break.* temporary files alongside lock markers.
  • Process: Two or more processes simultaneously executing code that should be mutually exclusive (detectable via application-level logging of "entered" events without intervening "left" events); unexpected concurrent writes to shared cache, install, or state directories.
  • Logs: Application logs showing a lock acquired by a second process before the first released it; filelock debug output showing owner_is_stale returning True for a PID that matches a running process; O_WRONLY|O_TRUNC opens of lock marker files by a UID different from the marker's owner (auditable via Linux auditd with -a always,exit -F arch=b64 -S open -F a1&0100=0 rules targeting the lock directory).
  • Network: No network-based IOCs — this is a purely local attack (GitHub Advisory).

Mitigation and workarounds

Upgrade filelock to version 4.2.1 or later, which fixes the vulnerability by stripping group and other write bits (S_IWGRP | S_IWOTH) from soft lock markers at both creation time and when applying an explicit mode via fchmod, regardless of the mode argument or umask (filelock 4.2.1 Release, Fix PR #836). As a workaround for systems that cannot immediately upgrade, avoid passing mode=0o666 (or any mode with group/other write bits) to SoftFileLock; use mode=0o644 or no explicit mode under umask 022 instead. Additionally, ensure lock files reside in directories that other accounts cannot write to, and avoid umask 002 or 000 for processes using soft locks in shared directories (GitHub Advisory).

Community reactions

The vulnerability was reported by Anthropic's automated OSS Scanner and reviewed by filelock maintainer gaborbernat, who opened a fix PR within approximately two hours of receiving the report and released the patch the following day. The advisory credits the automated analysis tool and notes the rapid turnaround from report to patch. No significant broader media coverage or notable community commentary beyond the GitHub advisory and associated Red Hat tracking entry has been observed at this time (GitHub Advisory, Red Hat CVE).

Additional resources

Linux Distribution fix status

Fix availability across major Linux distributions and their releases.

Debian

Affected

bookworm

python-filelock

Affected

sid

python-filelock

Affected

trixie

python-filelock

Affected

RHEL / CentOS

Affected

OpenShift

python-filelock.src

Affected

Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-112940HIGH7.1
  • Python logoPython
  • python-filelock
NoYesOct 20, 2026
CVE-2026-112937MEDIUM6.1
  • Python logoPython
  • python-filelock
NoYesOct 20, 2026
CVE-2026-112939MEDIUM4.7
  • Python logoPython
  • python-filelock
NoYesOct 20, 2026
CVE-2026-112941LOW3.3
  • Python logoPython
  • python-filelock
NoYesOct 20, 2026
GHSA-hq85-5cpj-mr62HIGHN/A
  • Python logoPython
  • uv
NoYesOct 20, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management