linux-stable/kernel/trace
Oleg Nesterov 649e9c70da tracing: Introduce trace_create_cpu_file() and tracing_get_cpu()
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>
2013-07-24 11:22:13 -04:00
..
blktrace.c Merge branch 'for-3.10/drivers' of git://git.kernel.dk/linux-block 2013-05-08 11:51:05 -07:00
ftrace.c ftrace: Do not run selftest if command line parameter is set 2013-07-01 20:57:15 -04:00
Kconfig ring-buffer: Select IRQ_WORK 2013-05-03 19:24:17 -04:00
Makefile trace: Stop compiling in trace_clock unconditionally 2012-09-13 22:52:08 -04:00
power-traces.c PM / tracing: remove deprecated power trace API 2013-01-26 00:39:12 +01:00
ring_buffer.c tracing: Typo fix on ring buffer comments 2013-07-18 21:31:26 -04:00
ring_buffer_benchmark.c
rpm-traces.c
trace.c tracing: Introduce trace_create_cpu_file() and tracing_get_cpu() 2013-07-24 11:22:13 -04:00
trace.h tracing: Kill trace_array->waiter 2013-07-19 10:56:02 -04:00
trace_branch.c tracing: Fix the branch tracer that broke with buffer change 2013-03-15 00:35:54 -04:00
trace_clock.c tracing: Add "uptime" trace clock that uses jiffies 2013-03-15 00:36:09 -04:00
trace_entries.h tracing: Add trace_puts() for even faster trace_printk() tracing 2013-03-15 00:35:55 -04:00
trace_event_perf.c tracing/perf: Move the PERF_MAX_TRACE_SIZE check into perf_trace_buf_prepare() 2013-07-18 21:31:28 -04:00
trace_events.c tracing: Do not (ab)use trace_seq in event_id_read() 2013-07-18 21:31:33 -04:00
trace_events_filter.c tracing: Use trace_seq_puts()/trace_seq_putc() where possible 2013-07-18 21:30:36 -04:00
trace_events_filter_test.h
trace_export.c tracing: Fix some section mismatch warnings 2013-03-15 00:34:54 -04:00
trace_functions.c tracing: Add ref_data to function and fgraph tracer structs 2013-07-18 21:31:31 -04:00
trace_functions_graph.c tracing: Add ref_data to function and fgraph tracer structs 2013-07-18 21:31:31 -04:00
trace_irqsoff.c tracing: Use flag buffer_disabled for irqsoff tracer 2013-07-01 20:34:28 -04:00
trace_kdb.c tracing: Consolidate max_tr into main trace_array structure 2013-03-15 00:35:40 -04:00
trace_kprobe.c tracing/kprobe: Wait for disabling all running kprobe handlers 2013-07-18 21:31:29 -04:00
trace_mmiotrace.c tracing: Use trace_seq_puts()/trace_seq_putc() where possible 2013-07-18 21:30:36 -04:00
trace_nop.c
trace_output.c tracing: Use trace_seq_puts()/trace_seq_putc() where possible 2013-07-18 21:30:36 -04:00
trace_output.h tracing: Rename trace_event_mutex to trace_event_sem 2013-03-15 13:22:10 -04:00
trace_printk.c tracing: Add percpu buffers for trace_printk() 2012-04-23 21:15:55 -04:00
trace_probe.c tracing: Replace strict_strto* with kstrto* 2012-10-31 16:45:23 -04:00
trace_probe.h uprobes/tracing: Introduce is_trace_uprobe_enabled() 2013-02-08 18:24:30 +01:00
trace_sched_switch.c tracing: Consolidate max_tr into main trace_array structure 2013-03-15 00:35:40 -04:00
trace_sched_wakeup.c tracing: Add function-trace option to disable function tracing of latency tracers 2013-03-15 00:36:08 -04:00
trace_selftest.c ftrace: Do not run selftest if command line parameter is set 2013-07-01 20:57:15 -04:00
trace_selftest_dynamic.c
trace_stack.c Tracing updates for Linux 3.10 2013-04-29 13:55:38 -07:00
trace_stat.c tracing: Check return value of tracing_init_dentry() 2013-04-12 23:02:32 -04:00
trace_stat.h
trace_syscalls.c tracing/perf: Move the PERF_MAX_TRACE_SIZE check into perf_trace_buf_prepare() 2013-07-18 21:31:28 -04:00
trace_uprobe.c tracing/perf: Move the PERF_MAX_TRACE_SIZE check into perf_trace_buf_prepare() 2013-07-18 21:31:28 -04:00