diff options
| author | Alexander Z Lam <azl@google.com> | 2013-07-01 22:37:54 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2013-07-01 23:30:08 -0400 |
| commit | a82274151af2b075163e3c42c828529dee311487 (patch) | |
| tree | 0923f9f765266925e9c800a461917ea312d3cc16 /kernel | |
| parent | 2d71619c59fac95a5415a326162fa046161b938c (diff) | |
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.
Link: http://lkml.kernel.org/r/1372732674-22726-1-git-send-email-azl@google.com
Cc: Vaibhav Nagarnaik <vnagarnaik@google.com>
Cc: David Sharp <dhsharp@google.com>
Cc: Alexander Z Lam <lambchop468@gmail.com>
Cc: stable@vger.kernel.org # 3.10
Signed-off-by: Alexander Z Lam <azl@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/trace/trace.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 11 |
3 files changed, 13 insertions, 2 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index e04e7119633d..e36da7ff59bf 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -266,7 +266,7 @@ static struct tracer *trace_types __read_mostly; | |||
| 266 | /* | 266 | /* |
| 267 | * trace_types_lock is used to protect the trace_types list. | 267 | * trace_types_lock is used to protect the trace_types list. |
| 268 | */ | 268 | */ |
| 269 | static DEFINE_MUTEX(trace_types_lock); | 269 | DEFINE_MUTEX(trace_types_lock); |
| 270 | 270 | ||
| 271 | /* | 271 | /* |
| 272 | * serialize the access of the ring buffer | 272 | * serialize the access of the ring buffer |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index a88939e666b7..2c3cba59552d 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -224,6 +224,8 @@ enum { | |||
| 224 | 224 | ||
| 225 | extern struct list_head ftrace_trace_arrays; | 225 | extern struct list_head ftrace_trace_arrays; |
| 226 | 226 | ||
| 227 | extern struct mutex trace_types_lock; | ||
| 228 | |||
| 227 | /* | 229 | /* |
| 228 | * The global tracer (top) should be the first trace array added, | 230 | * The global tracer (top) should be the first trace array added, |
| 229 | * but we check the flag anyway. | 231 | * but we check the flag anyway. |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 5892470bc2ee..35c6f23c71b2 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -1008,6 +1008,7 @@ static int subsystem_open(struct inode *inode, struct file *filp) | |||
| 1008 | int ret; | 1008 | int ret; |
| 1009 | 1009 | ||
| 1010 | /* Make sure the system still exists */ | 1010 | /* Make sure the system still exists */ |
| 1011 | mutex_lock(&trace_types_lock); | ||
| 1011 | mutex_lock(&event_mutex); | 1012 | mutex_lock(&event_mutex); |
| 1012 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 1013 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
| 1013 | list_for_each_entry(dir, &tr->systems, list) { | 1014 | list_for_each_entry(dir, &tr->systems, list) { |
| @@ -1023,6 +1024,7 @@ static int subsystem_open(struct inode *inode, struct file *filp) | |||
| 1023 | } | 1024 | } |
| 1024 | exit_loop: | 1025 | exit_loop: |
| 1025 | mutex_unlock(&event_mutex); | 1026 | mutex_unlock(&event_mutex); |
| 1027 | mutex_unlock(&trace_types_lock); | ||
| 1026 | 1028 | ||
| 1027 | if (!system) | 1029 | if (!system) |
| 1028 | return -ENODEV; | 1030 | return -ENODEV; |
| @@ -1617,6 +1619,7 @@ static void __add_event_to_tracers(struct ftrace_event_call *call, | |||
| 1617 | int trace_add_event_call(struct ftrace_event_call *call) | 1619 | int trace_add_event_call(struct ftrace_event_call *call) |
| 1618 | { | 1620 | { |
| 1619 | int ret; | 1621 | int ret; |
| 1622 | mutex_lock(&trace_types_lock); | ||
| 1620 | mutex_lock(&event_mutex); | 1623 | mutex_lock(&event_mutex); |
| 1621 | 1624 | ||
| 1622 | ret = __register_event(call, NULL); | 1625 | ret = __register_event(call, NULL); |
| @@ -1624,11 +1627,13 @@ int trace_add_event_call(struct ftrace_event_call *call) | |||
| 1624 | __add_event_to_tracers(call, NULL); | 1627 | __add_event_to_tracers(call, NULL); |
| 1625 | 1628 | ||
| 1626 | mutex_unlock(&event_mutex); | 1629 | mutex_unlock(&event_mutex); |
| 1630 | mutex_unlock(&trace_types_lock); | ||
| 1627 | return ret; | 1631 | return ret; |
| 1628 | } | 1632 | } |
| 1629 | 1633 | ||
| 1630 | /* | 1634 | /* |
| 1631 | * Must be called under locking both of event_mutex and trace_event_sem. | 1635 | * Must be called under locking of trace_types_lock, event_mutex and |
| 1636 | * trace_event_sem. | ||
| 1632 | */ | 1637 | */ |
| 1633 | static void __trace_remove_event_call(struct ftrace_event_call *call) | 1638 | static void __trace_remove_event_call(struct ftrace_event_call *call) |
| 1634 | { | 1639 | { |
| @@ -1640,11 +1645,13 @@ static void __trace_remove_event_call(struct ftrace_event_call *call) | |||
| 1640 | /* Remove an event_call */ | 1645 | /* Remove an event_call */ |
| 1641 | void trace_remove_event_call(struct ftrace_event_call *call) | 1646 | void trace_remove_event_call(struct ftrace_event_call *call) |
| 1642 | { | 1647 | { |
| 1648 | mutex_lock(&trace_types_lock); | ||
| 1643 | mutex_lock(&event_mutex); | 1649 | mutex_lock(&event_mutex); |
| 1644 | down_write(&trace_event_sem); | 1650 | down_write(&trace_event_sem); |
| 1645 | __trace_remove_event_call(call); | 1651 | __trace_remove_event_call(call); |
| 1646 | up_write(&trace_event_sem); | 1652 | up_write(&trace_event_sem); |
| 1647 | mutex_unlock(&event_mutex); | 1653 | mutex_unlock(&event_mutex); |
| 1654 | mutex_unlock(&trace_types_lock); | ||
| 1648 | } | 1655 | } |
| 1649 | 1656 | ||
| 1650 | #define for_each_event(event, start, end) \ | 1657 | #define for_each_event(event, start, end) \ |
| @@ -1788,6 +1795,7 @@ static int trace_module_notify(struct notifier_block *self, | |||
| 1788 | { | 1795 | { |
| 1789 | struct module *mod = data; | 1796 | struct module *mod = data; |
| 1790 | 1797 | ||
| 1798 | mutex_lock(&trace_types_lock); | ||
| 1791 | mutex_lock(&event_mutex); | 1799 | mutex_lock(&event_mutex); |
| 1792 | switch (val) { | 1800 | switch (val) { |
| 1793 | case MODULE_STATE_COMING: | 1801 | case MODULE_STATE_COMING: |
| @@ -1798,6 +1806,7 @@ static int trace_module_notify(struct notifier_block *self, | |||
| 1798 | break; | 1806 | break; |
| 1799 | } | 1807 | } |
| 1800 | mutex_unlock(&event_mutex); | 1808 | mutex_unlock(&event_mutex); |
| 1809 | mutex_unlock(&trace_types_lock); | ||
| 1801 | 1810 | ||
| 1802 | return 0; | 1811 | return 0; |
| 1803 | } | 1812 | } |
