CVE-2026-89791 in Linuxinfo

Summary

by MITRE • 09/16/2026

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

perf: Fix use-after-free when perf mmap() revival races with the last munmap()

perf_mmap_close() drops rb->mmap_count *without* holding event->mmap_mutex (the refcount_dec_and_test() right before the refcount_dec_and_mutex_lock() of event->mmap_count). A concurrent perf_mmap_rb() can slot its entire "revival" path into that window (perf_mmap holds event->mmap_mutex for its whole duration, including rb_alloc):

munmap side (perf_mmap_close) mmap side (perf_mmap_rb) ----------------------------------- -------------------------------- rb->mmap_count 1 -> 0 (no lock) (holds event->mmap_mutex) inc_not_zero(rb->mmap_count) fails ring_buffer_attach(event, NULL) rb_alloc() + attach new rb refcount_set(&event->mmap_count, 1) lock; event->mmap_count 1 -> 0 ring_buffer_attach(event, NULL) ring_buffer_put() -> frees the *new* rb

The revival's refcount_set(&event->mmap_count, 1) is an invisible 1 -> 1 write: the close frees the just-revived buffer although the other process still has it mapped -- a page-level use-after-free allowing local privilege escalation to root by any unprivileged user (default kernel.perf_event_paranoid=2).

Swap the order of the two counter updates: event->mmap_count is dropped first via refcount_dec_and_mutex_lock(), so its 1 -> 0 transition and the ring_buffer_attach() stay serialized with perf_mmap(). rb->mmap_count == 0 then implies every event using the buffer is detached already, so the result of the rb->mmap_count drop can gate the remaining teardown directly and detach_rest is no longer needed.

An earlier fix for this race from Kyle Zeng and David Lee takes event->mmap_mutex around both counter updates [0]; here the not-last
close stays lockless.

Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

Analysis

by VulDB Data Team • 09/16/2026

The Linux kernel's performance monitoring subsystem contains a critical use-after-free vulnerability arising from a race condition between memory mapping revivals and unmap operations. This flaw specifically affects the perf_mmap_close function, which is responsible for cleaning up memory-mapped regions associated with performance events. The core technical issue lies in the ordering of reference count decrements relative to mutex acquisition. Specifically, perf_mmap_close was dropping the ring buffer's mmap_count without holding the event-level mmap_mutex. This lack of synchronization created a window where concurrent operations could interfere destructively with each other, leading to premature memory deallocation while references were still active elsewhere in the system.

The operational impact is severe because this race condition allows for local privilege escalation to root by any unprivileged user under default kernel configurations. The vulnerability manifests when a munmap operation races against a perf_mmap_rb revival path. During this window, one thread may decrement the reference count to zero and proceed with cleanup while another thread attempts to revive or reattach the memory mapping. Because the synchronization primitives were not applied correctly around both counter updates, the system could free a ring buffer that was still being accessed by a live process. This constitutes a page-level use-after-free vulnerability where kernel memory is freed but remains accessible through active file descriptors or mappings, allowing an attacker to corrupt kernel state and execute arbitrary code with elevated privileges.

From a classification perspective, this issue aligns closely with CWE-416, Use After Free, as the root cause involves accessing memory after it has been released by another part of the program. In terms of adversarial tactics, this vulnerability facilitates privilege escalation which is often categorized under ATT&CK techniques related to local exploitation and kernel-level access. The flaw highlights a common pitfall in concurrent programming where partial locking strategies fail to protect critical sections that involve multiple state changes across different synchronization domains.

The resolution involves restructuring the order of operations within perf_mmap_close to ensure proper serialization with other mmap-related events. Instead of dropping the ring buffer's reference count before acquiring the event mutex, the fix mandates that the event-level mmap_count is dropped first using refcount_dec_and_mutex_lock. This ensures that the transition from one active mapping to zero is serialized correctly against any concurrent perf_mmap_rb calls. By holding the lock during both counter updates or ensuring the correct dependency order, the system guarantees that no new mappings can be attached while the teardown process is underway.

This approach also simplifies the cleanup logic by removing the need for a separate detach_rest mechanism when the ring buffer's mmap_count reaches zero. The previous implementation required additional checks to handle edge cases where references might linger due to the race window, but with proper locking order, rb_mmap_count equaling zero reliably indicates that all events using the buffer are already detached. This change not only fixes the security vulnerability but also improves code clarity and reduces complexity in the memory management path for performance monitoring buffers.

Responsible

Linux

Reservation

09/11/2026

Disclosure

09/16/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!