perf/core: Fix race in the perf_mmap_close() function
There's a possible race in perf_mmap_close() when checking ring buffer's
mmap_count refcount value. The problem is that the mmap_count check is
not atomic because we call atomic_dec() and atomic_read() separately.
<ring buffer detach>
ring_buffer_put(rb); /* could be last */
The race can happen when we have two (or more) events sharing same ring
buffer and they go through atomic_dec() and then they both see 0 as refcount
value later in atomic_read(). Then both will go on and execute code which
is meant to be run just once.
The code that detaches ring buffer is probably fine to be executed more
than once, but the problem is in calling free_uid(), which will later on
demonstrate in related crashes and refcount warnings, like:
refcount_t: addition on 0; use-after-free.
Using atomic decrease and check instead of separated calls.
Tested-by: Michael Petlan <firstname.lastname@example.org>
Signed-off-by: Jiri Olsa <email@example.com>
Signed-off-by: Ingo Molnar <firstname.lastname@example.org>
Acked-by: Peter Zijlstra <email@example.com>
Acked-by: Namhyung Kim <firstname.lastname@example.org>
Acked-by: Wade Mealing <email@example.com>
Fixes: 9bb5d40cd93c ("perf: Fix mmap() accounting hole");
1 file changed