summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2013-03-12 11:32:32 -0400
committerBen Hutchings <ben@decadent.org.uk>2013-03-27 02:41:12 +0000
commite28575118a7e1fe813363bbbc362d52eb64b4d4c (patch)
tree1564c7b4364c2179956423c74b294510f460bf7f
parent1deae276c803da39b36f5d5d6e5d850be122234f (diff)
tracing: Fix race in snapshot swapping
commit 2721e72dd10f71a3ba90f59781becf02638aa0d9 upstream. Although the swap is wrapped with a spin_lock, the assignment of the temp buffer used to swap is not within that lock. It needs to be moved into that lock, otherwise two swaps happening on two different CPUs, can end up using the wrong temp buffer to assign in the swap. Luckily, all current callers of the swap function appear to have their own locks. But in case something is added that allows two different callers to call the swap, then there's a chance that this race can trigger and corrupt the buffers. New code is coming soon that will allow for this race to trigger. I've Cc'd stable, so this bug will not show up if someone backports one of the changes that can trigger this bug. Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--kernel/trace/trace.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 563810461007..262d9df0aaa6 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -652,7 +652,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
void
update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
{
- struct ring_buffer *buf = tr->buffer;
+ struct ring_buffer *buf;
if (trace_stop_count)
return;
@@ -664,6 +664,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
}
arch_spin_lock(&ftrace_max_lock);
+ buf = tr->buffer;
tr->buffer = max_tr.buffer;
max_tr.buffer = buf;