perfcounters: fix use after free in perf_release()
running...
while true; do
foo -d 1 -f 1 -c 100000 & sleep 1
kerneltop -d 1 -f 1 -e 1 -c 25000 -p `pidof foo`
done
while true; do
killall foo; killall kerneltop; sleep 2
done
...in two shells with SLUB_DEBUG enabled produces flood of:
BUG task_struct: Poison overwritten.
Fix the use-after-free bug in perf_release().
Signed-off-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 89d5e3f..e0576c3 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1145,12 +1145,12 @@
mutex_lock(&counter->mutex);
perf_counter_remove_from_context(counter);
- put_context(ctx);
mutex_unlock(&counter->mutex);
mutex_unlock(&ctx->mutex);
kfree(counter);
+ put_context(ctx);
return 0;
}