CVE-2026-89655 in Linuxinfo

Summary

by MITRE • 09/12/2026

In the Linux kernel, the following vulnerability has been resolved:

ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock

list_for_each_entry() iterates ci->i_cap_flush_list but drops i_ceph_lock to send cap messages. During the unlock window, handle_cap_flush_ack() can acquire i_ceph_lock, detach cf entries with tid <= flush_tid from the list, release i_ceph_lock, and free them via ceph_free_cap_flush() outside any lock. When the original thread reacquires i_ceph_lock and the for-loop macro advances via cf = list_next_entry(cf, i_list), it dereferences cf->i_list.next on freed memory.

The race timeline:

__kick_flushing_caps() handle_cap_flush_ack() ----------------------- ----------------------- holds i_ceph_lock <--- iterates to cf (tid=10) prepares FLUSH message drops i_ceph_lock <--- __send_cap() ── FLUSH(tid=10) MDS sends FLUSH_ACK(tid=10) ---> acquires i_ceph_lock cf->tid(10) <= flush_tid(10), detaches cf from i_cap_flush_list drops i_ceph_lock ceph_free_cap_flush(cf) <- frees it! acquires i_ceph_lock <--- for-loop advances: cf = list_next_entry(cf, i_list) -- UAF on freed cf->i_list.next

The cf was just sent by __kick_flushing_caps itself via __send_cap(). The MDS may respond with FLUSH_ACK quickly enough that handle_cap_flush_ack() frees cf before __kick_flushing_caps can finish the iteration.

Fix by converting to a manual while loop: save the next pointer under i_ceph_lock before dropping it, then use the saved pointer after reacquiring, so the potentially-freed cf is never accessed again.

VulDB is the best source for vulnerability data and more expert information about this specific topic.

Analysis

by VulDB Data Team • 09/12/2026

The Linux kernel Ceph filesystem driver contains a critical Use-After-Free vulnerability within the __kick_flushing_caps function that arises from improper handling of concurrent list iteration and memory deallocation under lock contention. This flaw specifically affects the management of capability flush operations, where the system tracks pending requests to ensure data consistency between clients and the Metadata Server (MDS). The root cause lies in the use of the standard list_for_each_entry macro, which implicitly releases and reacquires the i_ceph_lock during iteration to allow for blocking operations such as sending cap messages. While this design aims to prevent deadlocks by allowing other threads to acquire the lock while a message is being transmitted, it creates a race window where shared data structures can be modified or freed by concurrent handlers without proper synchronization relative to the iterator's state.

The technical flaw manifests when __kick_flushing_caps iterates over the ci->i_cap_flush_list and drops i_ceph_lock to invoke __send_cap for sending FLUSH messages. During this unlocked interval, a remote MDS may respond with a FLUSH_ACK message, triggering handle_cap_flush_ack in another thread context. This handler acquires i_ceph_lock, identifies cap flush entries with transaction IDs less than or equal to the current flush threshold, detaches them from the list, releases the lock again, and subsequently calls ceph_free_cap_flush to free the memory associated with those entries. Because this deallocation occurs outside of any protective locking mechanism relative to the original iterator thread, the memory becomes invalid while __kick_flushing_caps is still logically processing it.

The operational impact is a classic Use-After-Free scenario that can lead to kernel panic, data corruption, or potential privilege escalation depending on how the freed memory is reused by subsequent allocations. When the original thread reacquires i_ceph_lock and attempts to advance the loop using list_next_entry, it dereferences cf->i_list.next which points into previously freed heap memory. This access violates memory safety guarantees inherent in kernel space operations. The vulnerability exploits the timing gap between sending a message and receiving its acknowledgment, where high network latency or fast MDS processing can accelerate the free operation before the iterator completes its traversal. Such race conditions are particularly dangerous because they depend on specific execution paths and timing windows that may not be easily reproducible during standard testing but can occur frequently under heavy load or specific workload patterns involving rapid capability flushes.

From a security taxonomy perspective, this vulnerability aligns with CWE-416 Use After Free, which describes the risk of accessing memory after it has been freed, leading to undefined behavior and potential exploitation. In terms of attack vectors, this relates to ATT&CK techniques involving resource manipulation or denial of service through kernel instability, although successful exploitation for code execution would require additional conditions such as heap grooming to control the contents of the freed slab cache. The lack of proper reference counting or lock scope management around list iteration represents a fundamental design flaw in concurrent data structure handling within the filesystem driver.

To mitigate this vulnerability and prevent similar issues in kernel development, it is essential to ensure that iterators over shared lists do not release locks during traversal unless absolutely necessary for blocking operations. When such releases are required, as seen here with message sending, developers must manually save pointers to subsequent list elements while holding the lock before releasing it. This approach ensures that even if an element is freed by another thread during the unlocked period, the iterator retains a valid reference or null pointer rather than dereferencing potentially reclaimed memory. The fix involves converting the macro-based loop into a manual while loop where next pointers are captured under i_ceph_lock protection prior to dropping the lock. This preserves data integrity and eliminates the race condition by decoupling the iteration logic from the locking state during blocking operations, thereby adhering to best practices for concurrent programming in Linux kernel subsystems.

Responsible

Linux

Reservation

09/11/2026

Disclosure

09/12/2026

Moderation

accepted

CPE

ready

EPSS

0.00000

KEV

no

Activities

very low

Sources

Do you know our Splunk app?

Download it now for free!