If we allocate perf ring buffer with the size of single page,
we will get memory corruption when releasing it. It's caused
by rb_free_work function (the CONFIG_PERF_USE_VMALLOC option
variant).

For single page sized ring buffer the page_order is -1 (because
nr_pages is 0). This needs to be recognized in the rb_free_work
function and set 'nr' to 0 in this case, so only the user page
gets freed.

Reported-by: Jan Stancek <jstan...@redhat.com>
Signed-off-by: Jiri Olsa <jo...@redhat.com>
Cc: Corey Ashford <cjash...@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweis...@gmail.com>
Cc: Ingo Molnar <mi...@elte.hu>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <a.p.zijls...@chello.nl>
Cc: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 kernel/events/ring_buffer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 23cb34f..21159fb 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -336,7 +336,8 @@ static void rb_free_work(struct work_struct *work)
        int i, nr;
 
        rb = container_of(work, struct ring_buffer, work);
-       nr = 1 << page_order(rb);
+       /* -1 if there's only user page */
+       nr = page_order(rb) == -1 ? 0 : 1 << page_order(rb);
 
        base = rb->user_page;
        for (i = 0; i < nr + 1; i++)
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to