forked from Minki/linux
ftrace: Fix kmemleak in unregister_ftrace_graph
The trampoline allocated by function tracer was overwriten by function_graph tracer, and caused a memory leak. The save_global_trampoline should have saved the previous trampoline in register_ftrace_graph() and restored it in unregister_ftrace_graph(). But as it is implemented, save_global_trampoline was only used in unregister_ftrace_graph as default value 0, and it overwrote the previous trampoline's value. Causing the previous allocated trampoline to be lost. kmmeleak backtrace: kmemleak_vmalloc+0x77/0xc0 __vmalloc_node_range+0x1b5/0x2c0 module_alloc+0x7c/0xd0 arch_ftrace_update_trampoline+0xb5/0x290 ftrace_startup+0x78/0x210 register_ftrace_function+0x8b/0xd0 function_trace_init+0x4f/0x80 tracing_set_tracer+0xe6/0x170 tracing_set_trace_write+0x90/0xd0 __vfs_write+0x37/0x170 vfs_write+0xb2/0x1b0 SyS_write+0x55/0xc0 do_syscall_64+0x67/0x180 return_from_SYSCALL_64+0x0/0x6a [ Looking further into this, I found that this was left over from when the function and function graph tracers shared the same ftrace_ops. But in commit5f151b2401
("ftrace: Fix function_profiler and function tracer together"), the two were separated, and the save_global_trampoline no longer was necessary (and it may have been broken back then too). -- Steven Rostedt ] Link: http://lkml.kernel.org/r/20170912021454.5976-1-shuwang@redhat.com Cc: stable@vger.kernel.org Fixes:5f151b2401
("ftrace: Fix function_profiler and function tracer together") Signed-off-by: Shu Wang <shuwang@redhat.com> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
parent
15516c89ac
commit
2b0b8499ae
@ -4954,9 +4954,6 @@ static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
|
||||
static char ftrace_graph_notrace_buf[FTRACE_FILTER_SIZE] __initdata;
|
||||
static int ftrace_graph_set_hash(struct ftrace_hash *hash, char *buffer);
|
||||
|
||||
static unsigned long save_global_trampoline;
|
||||
static unsigned long save_global_flags;
|
||||
|
||||
static int __init set_graph_function(char *str)
|
||||
{
|
||||
strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
|
||||
@ -6808,17 +6805,6 @@ void unregister_ftrace_graph(void)
|
||||
unregister_pm_notifier(&ftrace_suspend_notifier);
|
||||
unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
/*
|
||||
* Function graph does not allocate the trampoline, but
|
||||
* other global_ops do. We need to reset the ALLOC_TRAMP flag
|
||||
* if one was used.
|
||||
*/
|
||||
global_ops.trampoline = save_global_trampoline;
|
||||
if (save_global_flags & FTRACE_OPS_FL_ALLOC_TRAMP)
|
||||
global_ops.flags |= FTRACE_OPS_FL_ALLOC_TRAMP;
|
||||
#endif
|
||||
|
||||
out:
|
||||
mutex_unlock(&ftrace_lock);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user