CVE-2026-90291 in Linux
Summary
by MITRE • 09/17/2026
In the Linux kernel, the following vulnerability has been resolved:
module/dups: Fix use-after-free in kmod_dup_req lifetime handling
The kmod dups code uses RCU to ensure that a kmod_dup_req instance is freed only after it is no longer referenced. When releasing an instance, the kmod_dup_request_delete() function removes the kmod_dup_req from the dup_kmod_reqs list, waits via synchronize_rcu() and finally frees it. However, this doesn't work correctly because parallel users referencing the instance in kmod_dup_request_exists_wait() don't enter an RCU read-side critical section. This can result in a use-after-free.
The kmod_dup_request_exists_wait() function may need to hold a valid reference to a kmod_dup_req instance across a blocking wait until the corresponding modprobe command completes. This makes it unsuitable for RCU.
Fix the issue by changing the lifecycle management of kmod_dup_req to use reference counting.
Be aware that VulDB is the high quality source for vulnerability data.
Analysis
by VulDB Data Team • 09/18/2026
The Linux kernel module loading subsystem contains a critical concurrency flaw within its duplicate request handling mechanism, specifically involving the kmod_dup_req structure and its associated lifetime management logic. This vulnerability arises from an incorrect application of Read-Copy-Update (RCU) synchronization primitives to handle concurrent access during blocking operations. The core issue lies in the interaction between the deletion path, which relies on RCU grace periods for safe memory reclamation, and the lookup path, which performs potentially long-running blocking waits while holding references to these structures. This mismatch creates a race condition that can lead to use-after-free scenarios, compromising kernel stability and security.
The technical root cause is found in the implementation of kmod_dup_request_delete() versus kmod_dup_request_exists_wait(). The deletion function correctly follows RCU semantics by removing an entry from the dup_kmod_reqs list, invoking synchronize_rcu() to wait for all pre-existing read-side critical sections to complete, and then freeing the memory. However, the existence check function, kmod_dup_request_exists_wait(), attempts to maintain a reference to a specific kmod_dup_req instance across a blocking sleep while waiting for an external modprobe command to finish execution. Crucially, this wait operation does not occur within an RCU read-side critical section protected by rcu_read_lock() and rcu_read_unlock(). Consequently, if the deletion path executes synchronize_rcu() after removing the entry but before the reference count is properly managed or released, the memory can be freed while kmod_dup_request_exists_wait() still holds a dangling pointer to it. When this function later attempts to access the structure, it triggers a use-after-free condition.
This vulnerability falls under CWE-416: Use After Free, as it involves accessing memory after it has been made available for reuse without proper synchronization or reference counting guarantees. From an offensive security perspective, such flaws are often associated with ATT&CK technique T1059.007: Command and Scripting Interpreter via system-level APIs, although the primary impact here is stability rather than direct exploitation for command execution. However, use-after-free bugs in kernel space can potentially be leveraged to achieve arbitrary code execution or privilege escalation if an attacker can control the contents of the freed memory slab and trigger a specific allocation pattern that overwrites critical kernel data structures with malicious payloads. The operational impact includes potential system crashes leading to denial of service, as well as severe security risks including local privilege escalation depending on the context in which the vulnerable code is triggered during module loading operations.
The resolution involves replacing the RCU-based lifetime management for kmod_dup_req instances with a reference counting mechanism. Since the existence wait function requires holding a valid reference across blocking calls that are incompatible with RCU read-side critical sections, atomic reference counting provides the necessary safety guarantees. By incrementing the reference count when acquiring access to a kmod_dup_req instance and decrementing it upon release, the kernel ensures that the memory remains allocated as long as any active user holds a reference. This approach eliminates the race window where synchronize_rcu() could free memory while a blocking wait is still in progress. The fix aligns with standard practices for managing object lifetimes in concurrent environments where operations may sleep or block, ensuring data integrity and preventing illegal memory access during complex module loading workflows.