Commit bc6f6b08 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Steven Rostedt

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.comReviewed-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 1a11126b
...@@ -684,15 +684,25 @@ static ssize_t ...@@ -684,15 +684,25 @@ static ssize_t
event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
loff_t *ppos) loff_t *ppos)
{ {
struct ftrace_event_file *file = filp->private_data; struct ftrace_event_file *file;
unsigned long flags;
char buf[4] = "0"; char buf[4] = "0";
if (file->flags & FTRACE_EVENT_FL_ENABLED && mutex_lock(&event_mutex);
!(file->flags & FTRACE_EVENT_FL_SOFT_DISABLED)) file = event_file_data(filp);
if (likely(file))
flags = file->flags;
mutex_unlock(&event_mutex);
if (!file)
return -ENODEV;
if (flags & FTRACE_EVENT_FL_ENABLED &&
!(flags & FTRACE_EVENT_FL_SOFT_DISABLED))
strcpy(buf, "1"); strcpy(buf, "1");
if (file->flags & FTRACE_EVENT_FL_SOFT_DISABLED || if (flags & FTRACE_EVENT_FL_SOFT_DISABLED ||
file->flags & FTRACE_EVENT_FL_SOFT_MODE) flags & FTRACE_EVENT_FL_SOFT_MODE)
strcat(buf, "*"); strcat(buf, "*");
strcat(buf, "\n"); strcat(buf, "\n");
...@@ -704,13 +714,10 @@ static ssize_t ...@@ -704,13 +714,10 @@ static ssize_t
event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
loff_t *ppos) loff_t *ppos)
{ {
struct ftrace_event_file *file = filp->private_data; struct ftrace_event_file *file;
unsigned long val; unsigned long val;
int ret; int ret;
if (!file)
return -EINVAL;
ret = kstrtoul_from_user(ubuf, cnt, 10, &val); ret = kstrtoul_from_user(ubuf, cnt, 10, &val);
if (ret) if (ret)
return ret; return ret;
...@@ -722,8 +729,11 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, ...@@ -722,8 +729,11 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
switch (val) { switch (val) {
case 0: case 0:
case 1: case 1:
ret = -ENODEV;
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
ret = ftrace_event_enable_disable(file, val); file = event_file_data(filp);
if (likely(file))
ret = ftrace_event_enable_disable(file, val);
mutex_unlock(&event_mutex); mutex_unlock(&event_mutex);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment