CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-112906

CVE-2026-112906: Mutual Exclusion Bypass via Inode Recycling and Time Tracking Race in filelock

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 23, 2026·6 min read·6 visits

Executive Summary (TL;DR)

filelock versions 4.1.0-4.2.0 track stale locks using a tuple of inode number and modification time. An attacker can manipulate these properties on shared filesystems to trick waiters into deleting live locks, causing concurrent critical section access.

A local race condition and mutual exclusion bypass vulnerability exists in filelock versions 4.1.0 through 4.2.0. On Linux filesystems with rapid inode reuse, a local attacker can manipulate modification timestamps and lock files to cause waiting processes to falsely evict active soft lock markers.

Vulnerability Overview

The Python filelock library provides platform-independent file locking mechanisms utilized extensively across the Python package ecosystem. On POSIX systems where platform native file locking mechanisms like flock or fcntl are unavailable or configured to fall back to soft file locking primitives, filelock utilizes disk-based lock markers represented by SoftFileLock, MarkerSoftFileLock, and SoftFileLease objects.

Soft file locking relies on the presence of a specific marker file on disk to represent an active hold on a critical resource. To prevent deadlocks resulting from ungracefully terminated owner processes, the library implements a self-healing mechanism designed to detect stale lock markers. If a lock marker remains unchanged beyond a specified time threshold, contender processes assume the lock owner is inactive and automatically evict the marker file.

In versions 4.1.0 through 4.2.0, the heuristic used to identify unchanged lock files relied exclusively on a composite key of modification time (mtime) and inode number (ino). When deployed in shared environments such as /tmp on POSIX systems using filesystems with aggressive inode recycling (such as Linux ext4 or overlayfs), this identification mechanism fails. A local adversary can force new, legitimate lock files to match previously observed (mtime, ino) tuples, causing waiting processes to evict live lock markers and breaking mutual exclusion guarantees.

Root Cause Analysis

The primary flaw stems from relying on (mtime, ino) as a globally unique file identity key across time intervals without accounting for file descriptor lifetime or kernel metadata modification semantics. On POSIX filesystems, unprivileged local users possessing write permission to the lock directory can arbitrarily modify a file's mtime timestamp using system calls like utime() or utimensat().

When a file is unlinked on systems using ext4 or overlayfs, its allocated inode number $I$ is immediately returned to the allocator pool. Subsequent file creation operations within the same directory frequently reuse the newly freed inode number $I$. If the new file creation occurs within the same clock tick or timestamp interval $T$ manipulated by the adversary, the newly generated lock marker inherits the identical (mtime, ino) key combination $(T, I)$.

Because filelock tracked state across polling loops solely via this tuple, a contender process monitoring the lock path compares the new lock file against its cached observation state. Finding identical values for mtime and ino, the contender incorrectly calculates that the file has been unreferenced for longer than the stale lock threshold. Consequently, the contender process issues an eviction request against a newly created, valid lock file currently held by another active process.

Code Analysis

Prior to version 4.2.1, filelock tracked soft lock files using a simple state comparison method in src/filelock/_soft.py. The marker comparison logic only inspected st_mtime and st_ino from os.stat_result structures during state checks.

# Vulnerable tracking implementation in filelock <= 4.2.0
def _marker_unchanged_for(self, marker: os.stat_result) -> float:
    now: Final = time.monotonic()
    key: Final = marker.st_mtime, marker.st_ino  # Vulnerable key tuple
    if (seen := self._marker_seen) is None or seen[0] != key:
        self._marker_seen = key, now
        return 0.0
    return now - seen[1]

In patch commit 740ff666b62a88496c8d7394e4e6230605e4d62b, the core tracking function was modified to incorporate the kernel-managed change time (st_ctime_ns). While users can freely manipulate mtime, ctime is strictly controlled by the operating system kernel and reflects metadata changes, ensuring newly allocated files receive a distinct timestamp regardless of inode recycling.

# Patched implementation in filelock >= 4.2.1
def _marker_unchanged_for(self, marker: os.stat_result) -> float:
    now: Final = time.monotonic()
    # Fix: Added kernel-managed st_ctime_ns to key definition
    key: Final = marker.st_mtime, marker.st_ino, marker.st_ctime_ns
    if (seen := self._marker_seen) is None or seen[0] != key:
        self._marker_seen = key, now
        return 0.0
    return now - seen[1]

In addition to adding st_ctime_ns, the patch introduced inode pinning via open file descriptors (O_PATH / O_RDONLY with O_NOFOLLOW) to prevent inode reuse during state evaluation, alongside atomic filesystem exchange operations (renameat2 with RENAME_EXCHANGE on Linux) when evicting stale lock markers.

Exploitation Methodology

An exploitation scenario requires local access to the system and a shared directory where filelock soft lock files are generated (e.g., /tmp). The attacker does not require administrative privileges or special access beyond standard user file creation and modification rights in the shared directory.

To trigger the condition, the attacker creates a temporary file in the target lock directory and uses utime() to pre-date its modification time to a timestamp $T$. The attacker then unlinks the temporary file to return inode $I$ to the filesystem allocator pool. Contender processes actively polling the directory observe state $(T, I)$ during their loop iterations.

When a legitimate process attempts to acquire the lock, it creates a new marker file. On ext4 or overlayfs, the kernel assigns the newly freed inode $I$ to the file. If creation completes during timestamp interval $T$, the new file assumes key $(T, I)$. A waiting process checking the file matches the key against its stale cache record, concludes the lock is expired, and deletes the live lock marker. A secondary waiting process then creates a lock file in the vacant path, allowing two processes to enter the critical section simultaneously.

Impact Assessment

Exploitation of CVE-2026-112906 results in a complete loss of mutual exclusion integrity for applications relying on SoftFileLock, MarkerSoftFileLock, or SoftFileLease. When two processes enter protected critical sections simultaneously, data corruption, state inconsistency, and transactional race conditions occur.

The CVSS v3.1 vector is rated at 4.7 Medium (CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N). High attack complexity (AC:H) reflects the dependency on timing windows and filesystem-specific inode allocation behaviors. Local low-privileged access (AV:L/PR:L) is required.

This vulnerability does not directly expose read access to confidential memory or grant elevated privilege escalation on the host system. However, applications relying on file locking to synchronize file writes, database updates, or cache generation risk severe data corruption if compromised.

Remediation & Defensive Guidance

The primary remediation for CVE-2026-112906 is upgrading the filelock package to version 4.2.1 or higher. The fixed release includes kernel ctime tracking, open file descriptor pinning, and atomic lock swaps.

System administrators and application developers can apply dependency updates using standard Python package management tools:

pip install --upgrade "filelock>=4.2.1"

In environments where upgrading dependencies is delayed, application architectures should avoid utilizing global shared paths (such as /tmp or /var/tmp) for lock files. Configuring application lock directories within restricted, user-private paths (such as XDG_RUNTIME_DIR with 0700 permissions) prevents unprivileged local users from injecting pre-dated files or observing lock operations.

Official Patches

tox-devGitHub Security Advisory GHSA-2g95-wg33-c5x2
tox-devPull Request #843 containing the patch for stale lock race fixes
tox-devRelease v4.2.1 distribution tags

Fix Analysis (1)

Technical Appendix

CVSS Score
4.7/ 10
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N
EPSS Probability
0.21%
Top 90% most exploited

Affected Systems

Python environments utilizing filelock versions 4.1.0 through 4.2.0 on POSIX filesystems with active soft file locking

Affected Versions Detail

Product
Affected Versions
Fixed Version
filelock
tox-dev
>= 4.1.0, < 4.2.14.2.1
AttributeDetail
Vulnerability IDCVE-2026-112906 / GHSA-2g95-wg33-c5x2
Weakness EnumerationCWE-694 (Duplicate Identifier / Inode Race)
CVSS v3.1 Score4.7 (Medium)
EPSS Score0.00205 (10.01th percentile)
CISA KEV StatusNot Listed
Exploit MaturityProof of Concept / Test Suite
ImpactMutual Exclusion Bypass / Critical Section Race Condition

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
T1485Data Destruction
Impact
CWE-694
Use of Multiple Resources with Duplicate Identifier

The software reuses or relies on identifiers that are not guaranteed to be unique across file allocations, leading to resource misidentification and race conditions.

Known Exploits & Detection

GitHub Fix Commit Test SuiteReproduction test case added directly to the filelock repository verifying stale lock eviction race dynamics.

Vulnerability Timeline

Initial documentation and fix refactoring PR opened in repository.
2026-10-12
Security fix commit merged into tox-dev/filelock repository.
2026-10-17
GitHub Advisory GHSA-2g95-wg33-c5x2 and CVE-2026-112906 published; version 4.2.1 released on PyPI.
2026-10-20

References & Sources

  • [1]GitHub Security Advisory GHSA-2g95-wg33-c5x2
  • [2]Fix Commit 740ff666b62a88496c8d7394e4e6230605e4d62b
  • [3]Upstream Pull Request #843
  • [4]filelock v4.2.1 Release Notes
  • [5]NVD Vulnerability Detail CVE-2026-112906
  • [6]CVE Program Record CVE-2026-112906

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•5 minutes ago•CVE-2026-112937
6.1

CVE-2026-112937: Arbitrary Directory Deletion via TOCTOU Race Condition in filelock ReadWriteLock

A Time-of-Check Time-of-Use (TOCTOU) race condition in the Python `filelock` library (versions 4.1.0 to 4.2.0) allows local unprivileged attackers to cause arbitrary directory deletion by swapping file system targets during lock cleanup or dead owner sweeps.

Alon Barad
Alon Barad
0 views•5 min read
•about 2 hours ago•CVE-2026-114055
7.5

CVE-2026-114055: Uncontrolled Resource Consumption in vLLM via Unvalidated Multimodal Kwargs

vLLM prior to version 0.31.0 contains an uncontrolled resource consumption vulnerability (CWE-400) in its HTTP API request handling logic. Unauthenticated remote attackers can transmit per-request keyword arguments (`mm_processor_kwargs` and `media_io_kwargs`) that are passed directly into internal multimodal preprocessing pipelines, causing CPU/GPU memory exhaustion and crashing the engine process.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 3 hours ago•CVE-2026-62204
6.6

CVE-2026-62204: Arbitrary Bazaar Package Overwrite in SiYuan via Parameter Mismatch

An insufficient verification of data authenticity vulnerability in SiYuan prior to version 3.7.4 allows an attacker to overwrite arbitrary installed marketplace packages (plugins, widgets, themes, and templates). By providing a mismatched package name and package archive repository URL during a Bazaar installation request, arbitrary file write into trusted plugin directories can be achieved, enabling persistence and execution across application restarts.

Alon Barad
Alon Barad
7 views•5 min read
•about 4 hours ago•CVE-2026-115478
7.1

CVE-2026-115478: Incorrect Authorization and Incomplete Cleanup in obsidian-tc

In obsidian-tc versions 1.0.1 through 1.31.3, memory lifecycle tools fail to validate note ownership prior to rematerializing Markdown files and execute non-atomic SQLite database mutations. An authorized caller can overwrite arbitrary note bodies on disk and cause persistent desynchronization between the database memory graph and physical vault files.

Amit Schendel
Amit Schendel
8 views•5 min read
•about 5 hours ago•CVE-2026-115477
7.1

CVE-2026-115477: Human-in-the-Loop Authorization Bypass in obsidian-tc

A high-severity authorization bypass vulnerability in obsidian-tc allows clients to bypass Human-In-The-Loop (HITL) confirmation prompts over Streamable HTTP deployments. Due to incomplete validation of returned prompt responses, an attacker echoing a signed requestState token can force execution of destructive vault operations even if a human user declines or cancels the prompt.

Alon Barad
Alon Barad
10 views•5 min read
•about 6 hours ago•CVE-2026-113790
6.0

CVE-2026-113790: Uncontrolled Resource Consumption in pypdf Container Parsing

A Denial of Service (DoS) vulnerability in pypdf versions prior to 6.21.0 allows remote attackers to cause high CPU and memory resource exhaustion by supplying PDF files containing oversized or deeply nested arrays, dictionaries, or content streams.

Alon Barad
Alon Barad
8 views•5 min read