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

Commit 53ab6680 authored by Li Zefan's avatar Li Zefan Committed by Ingo Molnar
Browse files

ksym_tracer: Remove trace_stat



trace_stat is problematic. Don't use it, use seqfile instead.

This fixes a race that reading the stat file is not protected by
any lock, which can lead to use after free.

Signed-off-by: default avatarLi Zefan <lizf@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <4B3AF203.40200@cn.fujitsu.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent e6d9491b
Loading
Loading
Loading
Loading
+50 −77
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@
#include <linux/fs.h>

#include "trace_output.h"
#include "trace_stat.h"
#include "trace.h"

#include <linux/hw_breakpoint.h>
@@ -444,43 +443,21 @@ struct tracer ksym_tracer __read_mostly =
	.print_line	= ksym_trace_output
};

__init static int init_ksym_trace(void)
{
	struct dentry *d_tracer;
	struct dentry *entry;

	d_tracer = tracing_init_dentry();
	ksym_filter_entry_count = 0;

	entry = debugfs_create_file("ksym_trace_filter", 0644, d_tracer,
				    NULL, &ksym_tracing_fops);
	if (!entry)
		pr_warning("Could not create debugfs "
			   "'ksym_trace_filter' file\n");

	return register_tracer(&ksym_tracer);
}
device_initcall(init_ksym_trace);


#ifdef CONFIG_PROFILE_KSYM_TRACER
static int ksym_tracer_stat_headers(struct seq_file *m)
static int ksym_profile_show(struct seq_file *m, void *v)
{
	struct hlist_node *node;
	struct trace_ksym *entry;
	int access_type = 0;
	char fn_name[KSYM_NAME_LEN];

	seq_puts(m, "  Access Type ");
	seq_puts(m, "  Symbol                                       Counter\n");
	seq_puts(m, "  ----------- ");
	seq_puts(m, "  ------                                       -------\n");
	return 0;
}

static int ksym_tracer_stat_show(struct seq_file *m, void *v)
{
	struct hlist_node *stat = v;
	struct trace_ksym *entry;
	int access_type = 0;
	char fn_name[KSYM_NAME_LEN];

	entry = hlist_entry(stat, struct trace_ksym, ksym_hlist);
	rcu_read_lock();
	hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) {

		access_type = entry->attr.bp_type;

@@ -504,43 +481,39 @@ static int ksym_tracer_stat_show(struct seq_file *m, void *v)
			seq_printf(m, "  %-36s", "<NA>");
		seq_printf(m, " %15llu\n",
			   (unsigned long long)atomic64_read(&entry->counter));

	return 0;
	}
	rcu_read_unlock();

static void *ksym_tracer_stat_start(struct tracer_stat *trace)
{
	return ksym_filter_head.first;
	return 0;
}

static void *
ksym_tracer_stat_next(void *v, int idx)
static int ksym_profile_open(struct inode *node, struct file *file)
{
	struct hlist_node *stat = v;

	return stat->next;
	return single_open(file, ksym_profile_show, NULL);
}

static struct tracer_stat ksym_tracer_stats = {
	.name = "ksym_tracer",
	.stat_start = ksym_tracer_stat_start,
	.stat_next = ksym_tracer_stat_next,
	.stat_headers = ksym_tracer_stat_headers,
	.stat_show = ksym_tracer_stat_show
static const struct file_operations ksym_profile_fops = {
	.open		= ksym_profile_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
#endif /* CONFIG_PROFILE_KSYM_TRACER */

__init static int ksym_tracer_stat_init(void)
__init static int init_ksym_trace(void)
{
	int ret;
	struct dentry *d_tracer;

	ret = register_stat_tracer(&ksym_tracer_stats);
	if (ret) {
		printk(KERN_WARNING "Warning: could not register "
				    "ksym tracer stats\n");
		return 1;
	}
	d_tracer = tracing_init_dentry();

	return 0;
	trace_create_file("ksym_trace_filter", 0644, d_tracer,
			  NULL, &ksym_tracing_fops);

#ifdef CONFIG_PROFILE_KSYM_TRACER
	trace_create_file("ksym_profile", 0444, d_tracer,
			  NULL, &ksym_profile_fops);
#endif

	return register_tracer(&ksym_tracer);
}
fs_initcall(ksym_tracer_stat_init);
#endif /* CONFIG_PROFILE_KSYM_TRACER */
device_initcall(init_ksym_trace);