CVE-2026-99111 in Linux
Summary
by MITRE • 10/28/2026
In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix data corruption with concurrent writes and O_TRUNC
cifs_do_truncate() flushes dirty pages with filemap_write_and_wait() and truncates the file on the server, but in the old code both operations ran without holding i_rwsem or invalidate_lock. A concurrent buffered write via netfs_perform_write() -- which only needs i_rwsem shared -- could dirty new pages after the flush but before the local truncation, and those pages would be silently discarded by cifs_setsize() -> truncate_pagecache().
Fix by acquiring inode_lock (exclusive i_rwsem) and filemap_invalidate_lock at the top of cifs_do_truncate(), so the entire flush-truncate-resize sequence is atomic with respect to:
- buffered writes (blocked by exclusive i_rwsem, since netfs_start_io_write takes i_rwsem shared), - read page faults (blocked by exclusive invalidate_lock, since filemap_fault takes it shared), - writeback collection (blocked by netfs_wb_begin/netfs_wb_end around the server truncate and local resize, since netfs_writepages also acquires the wb lock).
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.
Analysis
by VulDB Data Team • 10/28/2026
The Linux kernel SMB client implementation contained a critical race condition within the file truncation logic that led to silent data corruption. This vulnerability specifically affected scenarios where concurrent write operations occurred alongside an operation to truncate or shrink a file size, such as when opening a file with the O_TRUNC flag. The core of the issue lay in the cifs_do_truncate function, which was responsible for flushing dirty pages from the local cache to the server and subsequently truncating the file on both the local system and the remote SMB share. In the flawed implementation, these two critical operations were executed without holding the necessary inode locks or invalidation locks. This lack of synchronization created a window where concurrent buffered writes could modify data after the flush operation had completed but before the local page cache was truncated to reflect the new file size.
The technical flaw stems from insufficient locking granularity during the truncate sequence. When cifs_do_truncate initiated, it called filemap_write_and_wait to ensure all pending dirty pages were written back to the server. However, because this process did not acquire an exclusive lock on the inode's read-write semaphore (i_rwsem) or the invalidate_lock, other threads could proceed with write operations in parallel. Specifically, a concurrent buffered write via netfs_perform_write only requires shared access to i_rwsem. This allowed such writes to dirty new pages after the flush had finished but before the local truncation took effect. When cifs_setsize subsequently called truncate_pagecache to resize the file locally, it would silently discard these newly dirtied pages because they fell outside the new, smaller file size boundaries. The result was that data written by concurrent processes was lost without any error indication, leading to severe data integrity issues for applications relying on SMB mounts for storage.
The operational impact of this vulnerability is significant, particularly in environments where multiple clients or threads frequently write to and truncate files over SMB shares. Data loss can occur unpredictably depending on the timing of writes relative to truncation operations. This affects a wide range of workloads including database transactions, log rotation scripts, and any application that relies on atomic file size adjustments combined with concurrent I/O. The silent nature of the data discard makes debugging difficult, as there are no immediate error codes returned; instead, users experience missing or corrupted data after what appears to be successful write operations. This undermines the reliability guarantees expected from network filesystems and can lead to application-level failures if critical files are partially overwritten or truncated unexpectedly.
To resolve this issue, the fix involves acquiring both an exclusive lock on i_rwsem (via inode_lock) and filemap_invalidate_lock at the beginning of cifs_do_truncate. This ensures that the entire sequence of flushing dirty pages, truncating the file on the server, and resizing the local page cache is atomic with respect to concurrent operations. The exclusive i_rwsem prevents buffered writes from modifying data during this window, as netfs_start_io_write requires shared access which is blocked by the exclusive lock. Similarly, read page faults are prevented because they require shared access to invalidate_lock, which is held exclusively. Additionally, writeback collection is synchronized using netfs_wb_begin and netfs_wb_end around the server truncate and local resize operations, ensuring consistency with how netfs_writepages handles locking. This comprehensive locking strategy eliminates the race condition by serializing conflicting I/O paths during file size modifications.
From a vulnerability classification perspective, this issue aligns with CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization (Race Condition). The lack of proper mutual exclusion when accessing shared state (the inode and page cache) allowed for unsafe concurrent access that resulted in data loss. In terms of the MITRE ATT&CK framework, while this is not an exploit vector for unauthorized access or privilege escalation, it represents a failure in system integrity controls. It can be categorized under techniques related to resource manipulation where availability and consistency are compromised due to implementation flaws rather than malicious exploitation. The fix reinforces best practices in kernel development by ensuring that compound operations involving multiple state changes (flushing and truncating) are protected by appropriate synchronization primitives to maintain data consistency across distributed storage systems.