Skip to content

Commit f74b9f4

Browse files
committed
perf/core: Handle buffer mapping fail correctly in perf_mmap()
After successful allocation of a buffer or a successful attachment to an existing buffer perf_mmap() tries to map the buffer read only into the page table. If that fails, the already set up page table entries are zapped, but the other perf specific side effects of that failure are not handled. The calling code just cleans up the VMA and does not invoke perf_mmap_close(). This leaks reference counts, corrupts user->vm accounting and also results in an unbalanced invocation of event::event_mapped(). Cure this by moving the event::event_mapped() invocation before the map_range() call so that on map_range() failure perf_mmap_close() can be invoked without causing an unbalanced event::event_unmapped() call. perf_mmap_close() undoes the reference counts and eventually frees buffers. Fixes: b709eb8 ("perf: map pages in advance") Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Lorenzo Stoakes <[email protected]> Cc: [email protected]
1 parent 07091aa commit f74b9f4

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

kernel/events/core.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7148,12 +7148,20 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
71487148
vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP);
71497149
vma->vm_ops = &perf_mmap_vmops;
71507150

7151-
ret = map_range(rb, vma);
7152-
71537151
mapped = get_mapped(event, event_mapped);
71547152
if (mapped)
71557153
mapped(event, vma->vm_mm);
71567154

7155+
/*
7156+
* Try to map it into the page table. On fail, invoke
7157+
* perf_mmap_close() to undo the above, as the callsite expects
7158+
* full cleanup in this case and therefore does not invoke
7159+
* vmops::close().
7160+
*/
7161+
ret = map_range(rb, vma);
7162+
if (ret)
7163+
perf_mmap_close(vma);
7164+
71577165
return ret;
71587166
}
71597167

0 commit comments

Comments
 (0)