diff --git a/kernel/events/core.c b/kernel/events/core.c index cdef6ae43f4a7c8deaa9ab69594057c19ea7d765..6b572eb3fede4a8448299c90c1af3e25c3b8b894 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6467,11 +6467,21 @@ static void perf_mmap_close(struct vm_area_struct *vma) ring_buffer_put(rb); /* could be last */ } +static int perf_mmap_may_split(struct vm_area_struct *vma, unsigned long addr) +{ + /* + * Forbid splitting perf mappings to prevent refcount leaks due to + * the resulting non-matching offsets and sizes. See open()/close(). + */ + return -EINVAL; +} + static const struct vm_operations_struct perf_mmap_vmops = { .open = perf_mmap_open, .close = perf_mmap_close, /* non mergeable */ .fault = perf_mmap_fault, .page_mkwrite = perf_mmap_fault, + .may_split = perf_mmap_may_split, }; static int perf_mmap(struct file *file, struct vm_area_struct *vma)