aboutsummaryrefslogtreecommitdiff
path: root/kernel/trace/trace_stack.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-07-23 17:25:54 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-29 09:47:32 -0700
commite2d4dbe02175e54616fe52c4e9c367199f8ecdaa (patch)
tree6e23d7e01e1df9a4e635e3f288ca722bf8310d6b /kernel/trace/trace_stack.c
parente899e7e4f83ecd606e85d355410d724ec76542cb (diff)
tracing: Introduce trace_create_cpu_file() and tracing_get_cpu()
commit 649e9c70da6bfbeb563193a35d3424a5aa7c0d38 upstream. Every "file_operations" used by tracing_init_debugfs_percpu is buggy. f_op->open/etc does: 1. struct trace_cpu *tc = inode->i_private; struct trace_array *tr = tc->tr; 2. trace_array_get(tr) or fail; 3. do_something(tc); But tc (and tr) can be already freed before trace_array_get() is called. And it doesn't matter whether this file is per-cpu or it was created by init_tracer_debugfs(), free_percpu() or kfree() are equally bad. Note that even 1. is not safe, the freed memory can be unmapped. But even if it was safe trace_array_get() can wrongly succeed if we also race with the next new_instance_create() which can re-allocate the same tr, or tc was overwritten and ->tr points to the valid tr. In this case 3. uses the freed/reused memory. Add the new trivial helper, trace_create_cpu_file() which simply calls trace_create_file() and encodes "cpu" in "struct inode". Another helper, tracing_get_cpu() will be used to read cpu_nr-or-RING_BUFFER_ALL_CPUS. The patch abuses ->i_cdev to encode the number, it is never used unless the file is S_ISCHR(). But we could use something else, say, i_bytes or even ->d_fsdata. In any case this hack is hidden inside these 2 helpers, it would be trivial to change them if needed. This patch only changes tracing_init_debugfs_percpu() to use the new trace_create_cpu_file(), the next patches will change file_operations. Note: tracing_get_cpu(inode) is always safe but you can't trust the result unless trace_array_get() was called, without trace_types_lock which acts as a barrier it can wrongly return RING_BUFFER_ALL_CPUS. Link: http://lkml.kernel.org/r/20130723152554.GA23710@redhat.com Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel/trace/trace_stack.c')
0 files changed, 0 insertions, 0 deletions