aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-07-26 13:25:36 -0400
committerSteven Rostedt <rostedt@goodmis.org>2013-07-29 22:05:40 -0400
commitbc6f6b08dee5645770efb4b76186ded313f23752 (patch)
tree4f2a94646a39b8454e21bed38f093f73c8752345 /kernel
parent1a11126bcb7c93c289bf3218fa546fd3b0c0df8b (diff)
tracing: Change event_enable/disable_read() to verify i_private != NULL
tracing_open_generic_file() is racy, ftrace_event_file can be already freed by rmdir or trace_remove_event_call(). Change event_enable_read() and event_disable_read() to read and verify "file = i_private" under event_mutex. This fixes nothing, but now we can change debugfs_remove("enable") callers to nullify ->i_private and fix the the problem. Link: http://lkml.kernel.org/r/20130726172536.GA3612@redhat.com Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_events.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index c2d13c528c3c..3dfa8419d0dc 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -684,15 +684,25 @@ static ssize_t
684event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, 684event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
685 loff_t *ppos) 685 loff_t *ppos)
686{ 686{
687 struct ftrace_event_file *file = filp->private_data; 687 struct ftrace_event_file *file;
688 unsigned long flags;
688 char buf[4] = "0"; 689 char buf[4] = "0";
689 690
690 if (file->flags & FTRACE_EVENT_FL_ENABLED && 691 mutex_lock(&event_mutex);
691 !(file->flags & FTRACE_EVENT_FL_SOFT_DISABLED)) 692 file = event_file_data(filp);
693 if (likely(file))
694 flags = file->flags;
695 mutex_unlock(&event_mutex);
696
697 if (!file)
698 return -ENODEV;
699
700 if (flags & FTRACE_EVENT_FL_ENABLED &&
701 !(flags & FTRACE_EVENT_FL_SOFT_DISABLED))
692 strcpy(buf, "1"); 702 strcpy(buf, "1");
693 703
694 if (file->flags & FTRACE_EVENT_FL_SOFT_DISABLED || 704 if (flags & FTRACE_EVENT_FL_SOFT_DISABLED ||
695 file->flags & FTRACE_EVENT_FL_SOFT_MODE) 705 flags & FTRACE_EVENT_FL_SOFT_MODE)
696 strcat(buf, "*"); 706 strcat(buf, "*");
697 707
698 strcat(buf, "\n"); 708 strcat(buf, "\n");
@@ -704,13 +714,10 @@ static ssize_t
704event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, 714event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
705 loff_t *ppos) 715 loff_t *ppos)
706{ 716{
707 struct ftrace_event_file *file = filp->private_data; 717 struct ftrace_event_file *file;
708 unsigned long val; 718 unsigned long val;
709 int ret; 719 int ret;
710 720
711 if (!file)
712 return -EINVAL;
713
714 ret = kstrtoul_from_user(ubuf, cnt, 10, &val); 721 ret = kstrtoul_from_user(ubuf, cnt, 10, &val);
715 if (ret) 722 if (ret)
716 return ret; 723 return ret;
@@ -722,8 +729,11 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
722 switch (val) { 729 switch (val) {
723 case 0: 730 case 0:
724 case 1: 731 case 1:
732 ret = -ENODEV;
725 mutex_lock(&event_mutex); 733 mutex_lock(&event_mutex);
726 ret = ftrace_event_enable_disable(file, val); 734 file = event_file_data(filp);
735 if (likely(file))
736 ret = ftrace_event_enable_disable(file, val);
727 mutex_unlock(&event_mutex); 737 mutex_unlock(&event_mutex);
728 break; 738 break;
729 739