linux/kernel/trace
Lai Jiangshan 4f5359685a tracing: add trace_event_read_lock()
I found that there is nothing to protect event_hash in
ftrace_find_event(). Rcu protects the event hashlist
but not the event itself while we use it after its extraction
through ftrace_find_event().

This lack of a proper locking in this spot opens a race
window between any event dereferencing and module removal.

Eg:

--Task A--

print_trace_line(trace) {
  event = find_ftrace_event(trace)

--Task B--

trace_module_remove_events(mod) {
  list_trace_events_module(ev, mod) {
    unregister_ftrace_event(ev->event) {
      hlist_del(ev->event->node)
        list_del(....)
    }
  }
}
|--> module removed, the event has been dropped

--Task A--

  event->print(trace); // Dereferencing freed memory

If the event retrieved belongs to a module and this module
is concurrently removed, we may end up dereferencing a data
from a freed module.

RCU could solve this, but it would add latency to the kernel and
forbid tracers output callbacks to call any sleepable code.
So this fix converts 'trace_event_mutex' to a read/write semaphore,
and adds trace_event_read_lock() to protect ftrace_find_event().

[ Impact: fix possible freed memory dereference in ftrace ]

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <4A114806.7090302@cn.fujitsu.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
2009-05-25 23:53:41 +02:00
..
Kconfig tracing: have menu default enabled when kernel debug is configured 2009-05-07 12:49:27 -04:00
Makefile Merge branch 'tracing/hw-branch-tracing' into tracing/core 2009-05-07 13:36:22 +02:00
blktrace.c blktrace: remove debugfs entries on bad path 2009-05-19 10:29:21 +02:00
ftrace.c tracing: fix check for return value of register_module_notifier 2009-05-18 10:24:13 +02:00
kmemtrace.c tracing/filters: use ring_buffer_discard_commit() in filter_check_discard() 2009-04-14 00:00:56 +02:00
ring_buffer.c ring-buffer: move code around to remove some branches 2009-05-11 23:33:06 -04:00
ring_buffer_benchmark.c ring-buffer: check for divide by zero in ring-buffer-benchmark 2009-05-11 13:22:26 -04:00
trace.c tracing: add trace_event_read_lock() 2009-05-25 23:53:41 +02:00
trace.h Merge branch 'tracing/hw-branch-tracing' into tracing/core 2009-05-07 13:36:22 +02:00
trace_boot.c tracing: use macros to denote usec and nsec per second 2009-04-07 14:43:06 +02:00
trace_branch.c Merge branch 'linus' into tracing/core 2009-05-07 11:17:34 +02:00
trace_clock.c tracing: fix four sparse warnings 2009-03-22 18:16:54 +01:00
trace_event_profile.c tracing/events: fix concurrent access to ftrace_events list 2009-05-06 10:38:19 +02:00
trace_event_types.h tracing/filters: distinguish between signed and unsigned fields 2009-04-29 14:06:03 +02:00
trace_events.c ftrace: fix check for return value of register_module_notifier in event_trace_init 2009-05-20 19:23:11 +02:00
trace_events_filter.c tracing/filters: fix off-by-one bug 2009-05-14 23:55:12 -04:00
trace_export.c tracing/filters: distinguish between signed and unsigned fields 2009-04-29 14:06:03 +02:00
trace_functions.c tracing/core: use appropriate waiting on trace_pipe 2009-02-18 01:40:20 +01:00
trace_functions_graph.c function-graph: add option to calculate graph time or not 2009-03-24 23:41:11 -04:00
trace_hw_branches.c Merge branch 'tracing/hw-branch-tracing' into tracing/core 2009-05-07 13:36:22 +02:00
trace_irqsoff.c tracing: have latency tracers set the latency format 2009-03-04 22:15:30 -05:00
trace_mmiotrace.c tracing: use macros to denote usec and nsec per second 2009-04-07 14:43:06 +02:00
trace_nop.c tracing/ftrace: make nop-tracer use polling wait for events on pipe 2009-03-23 09:22:15 +01:00
trace_output.c tracing: add trace_event_read_lock() 2009-05-25 23:53:41 +02:00
trace_output.h tracing: add trace_event_read_lock() 2009-05-25 23:53:41 +02:00
trace_power.c Merge branch 'linus' into tracing/core 2009-05-07 11:17:34 +02:00
trace_printk.c tracing/ftrace: factorize the tracing files creation 2009-04-07 14:43:07 +02:00
trace_sched_switch.c tracing/events: move trace point headers into include/trace/events 2009-04-14 22:05:43 -04:00
trace_sched_wakeup.c tracing/wakeup: move access to wakeup_cpu into spinlock 2009-04-23 23:01:36 -04:00
trace_selftest.c x86, hw-branch-tracer: allocate selftest iterator on heap 2009-04-07 13:36:21 +02:00
trace_selftest_dynamic.c ftrace: fix dynamic ftrace selftest 2008-05-23 21:13:23 +02:00
trace_stack.c tracing/ftrace: factorize the tracing files creation 2009-04-07 14:43:07 +02:00
trace_stat.c Merge branch 'linus' into tracing/core 2009-04-07 13:47:45 +02:00
trace_stat.h tracing: add handler to trace_stat 2009-03-24 23:22:58 -04:00
trace_syscalls.c tracing/syscalls: use a dedicated file header 2009-04-09 05:43:32 +02:00
trace_sysprof.c tracing/ftrace: factorize the tracing files creation 2009-04-07 14:43:07 +02:00
trace_workqueue.c Merge branch 'linus' into tracing/core 2009-04-07 13:47:45 +02:00