tracing: Protect ftrace_trace_arrays list in trace_events.c
PATCH v2 1/1 tracing: Protect ftrace_trace_arrays list in trace_events.c
There are multiple places where the ftrace_trace_arrays list is accessed in trace_events.c without the trace_types_lock held.
Cc David Sharp <[email protected]>
Cc Alexander Z Lam <[email protected]>
Signed-off-by Alexander Z Lam <[email protected]>
--- kernel/trace/trace.c | 2 +- kernel/trace/trace.h | 2 ++ kernel/trace/trace_events.c | 11 ++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-)
kernel/trace/trace.c +1 -1
@@ -245,7 +245,7 @@ static struct tracer *trace_types __read_mostly;/* * trace_types_lock is used to protect the trace_types list. */ -static DEFINE_MUTEX (trace_types_lock); +DEFINE_MUTEX (trace_types_lock);/* * serialize the access of the ring buffer
kernel/trace/trace.h +2 -0
@@ -225,6 +225,8 @@ enum {extern struct list_head ftrace_trace_arrays; +extern struct mutex trace_types_lock; +/* * The global tracer (top) should be the first trace array added, * but we check the flag anyway.
kernel/trace/trace_events.c +10 -1
@@ -987,6 +987,7 @@ static int subsystem_open(struct inode *inode, struct file *filp)int ret;/* Make sure the system still exists */ +mutex_lock (&trace_types_lock);mutex_lock (&event_mutex);list_for_each_entry (tr, &ftrace_trace_arrays, list) {list_for_each_entry (dir, &tr->systems, list) {
@@ -1002,6 +1003,7 @@ static int subsystem_open(struct inode *inode, struct file *filp) } exit_loop:mutex_unlock (&event_mutex); +mutex_unlock (&trace_types_lock);if (!system)return -ENODEV ;
@@ -1586,6 +1588,7 @@ static void __add_event_to_tracers(struct ftrace_event_call *call,int trace_add_event_call (struct ftrace_event_call *call) {int ret; +mutex_lock (&trace_types_lock);mutex_lock (&event_mutex); ret =__register_event (call,NULL );
@@ -1593,11 +1596,13 @@ int trace_add_event_call(struct ftrace_event_call *call)__add_event_to_tracers (call,NULL );mutex_unlock (&event_mutex); +mutex_unlock (&trace_types_lock);return ret; }/* -* Must be called under locking both of event_mutex and trace_event_sem. +* Must be called under locking of trace_types_lock, event_mutex and +* trace_event_sem. */ static void __trace_remove_event_call (struct ftrace_event_call *call) {
@@ -1609,11 +1614,13 @@ static void __trace_remove_event_call(struct ftrace_event_call *call)/* Remove an event_call */ void trace_remove_event_call (struct ftrace_event_call *call) { +mutex_lock (&trace_types_lock);mutex_lock (&event_mutex);down_write (&trace_event_sem);__trace_remove_event_call (call);up_write (&trace_event_sem);mutex_unlock (&event_mutex); +mutex_unlock (&trace_types_lock); }#define for_each_event (event, start, end) \
@@ -1757,6 +1764,7 @@ static int trace_module_notify(struct notifier_block *self, {struct module *mod = data; +mutex_lock (&trace_types_lock);mutex_lock (&event_mutex);switch (val) {case MODULE_STATE_COMING :
@@ -1767,6 +1775,7 @@ static int trace_module_notify(struct notifier_block *self,break ; }mutex_unlock (&event_mutex); +mutex_unlock (&trace_types_lock);return 0 ; }
Signature · 1 line
1.8.3