Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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: 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
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -684,15 +684,25 @@ static ssize_t
event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
		  loff_t *ppos)
{
	struct ftrace_event_file *file = filp->private_data;
	struct ftrace_event_file *file;
	unsigned long flags;
	char buf[4] = "0";

	if (file->flags & FTRACE_EVENT_FL_ENABLED &&
	    !(file->flags & FTRACE_EVENT_FL_SOFT_DISABLED))
	mutex_lock(&event_mutex);
	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");

	if (file->flags & FTRACE_EVENT_FL_SOFT_DISABLED ||
	    file->flags & FTRACE_EVENT_FL_SOFT_MODE)
	if (flags & FTRACE_EVENT_FL_SOFT_DISABLED ||
	    flags & FTRACE_EVENT_FL_SOFT_MODE)
		strcat(buf, "*");

	strcat(buf, "\n");
@@ -704,13 +714,10 @@ static ssize_t
event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
		   loff_t *ppos)
{
	struct ftrace_event_file *file = filp->private_data;
	struct ftrace_event_file *file;
	unsigned long val;
	int ret;

	if (!file)
		return -EINVAL;

	ret = kstrtoul_from_user(ubuf, cnt, 10, &val);
	if (ret)
		return ret;
@@ -722,7 +729,10 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
	switch (val) {
	case 0:
	case 1:
		ret = -ENODEV;
		mutex_lock(&event_mutex);
		file = event_file_data(filp);
		if (likely(file))
			ret = ftrace_event_enable_disable(file, val);
		mutex_unlock(&event_mutex);
		break;