Merge tag 'perf-urgent-2026-09-06' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf events fixes from Ingo Molnar:

 - Skip empty AUX records with only format flags (Leo Yan)

 - Fix use-after-free when perf mmap() revival races with the
   last munmap() (Yilin Zhang, Weiming Shi)

* tag 'perf-urgent-2026-09-06' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf: Fix use-after-free when perf mmap() revival races with the last munmap()
  perf/core: Skip empty AUX records with only format flags
This commit is contained in:
Linus Torvalds
2026-09-06 11:06:09 -07:00
2 changed files with 17 additions and 12 deletions
+10 -10
View File
@@ -7029,7 +7029,6 @@ static void perf_mmap_close(struct vm_area_struct *vma)
mapped_f unmapped = get_mapped(event, event_unmapped);
struct perf_buffer *rb = ring_buffer_get(event);
struct user_struct *mmap_user = rb->mmap_user;
bool detach_rest = false;
/* FIXIES vs perf_pmu_unregister() */
if (unmapped)
@@ -7060,17 +7059,18 @@ static void perf_mmap_close(struct vm_area_struct *vma)
mutex_unlock(&rb->aux_mutex);
}
if (refcount_dec_and_test(&rb->mmap_count))
detach_rest = true;
if (!refcount_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex))
goto out_put;
ring_buffer_attach(event, NULL);
mutex_unlock(&event->mmap_mutex);
/*
* Drop references in reverse order of perf_mmap() to prevent
* rb revival after rb->mmap_count reaches zero.
*/
if (refcount_dec_and_mutex_lock(&event->mmap_count,
&event->mmap_mutex)) {
ring_buffer_attach(event, NULL);
mutex_unlock(&event->mmap_mutex);
}
/* If there's still other mmap()s of this buffer, we're done. */
if (!detach_rest)
if (!refcount_dec_and_test(&rb->mmap_count))
goto out_put;
/*
+7 -2
View File
@@ -509,7 +509,10 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
/*
* Only send RECORD_AUX if we have something useful to communicate
*
* Note: the OVERWRITE records by themselves are not considered
* PMU_FORMAT bits identify the PMU type rather than an AUX event
* has occurred, so ignore them for zero-sized records.
*
* The OVERWRITE records by themselves are not considered
* useful, as they don't communicate any *new* information,
* aside from the short-lived offset, that becomes history at
* the next event sched-in and therefore isn't useful.
@@ -518,7 +521,9 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
* offset. So, from now on we don't output AUX records that
* have *only* OVERWRITE flag set.
*/
if (size || (handle->aux_flags & ~(u64)PERF_AUX_FLAG_OVERWRITE))
if (size ||
(handle->aux_flags & ~(u64)(PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK |
PERF_AUX_FLAG_OVERWRITE)))
perf_event_aux_event(handle->event, aux_head, size,
handle->aux_flags);