| From 8b0db1a5bdfcee0dbfa89607672598ae203c9045 Mon Sep 17 00:00:00 2001 |
| From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> |
| Date: Wed, 23 Aug 2017 12:46:27 -0400 |
| Subject: tracing: Fix freeing of filter in create_filter() when set_str is false |
| |
| From: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| |
| commit 8b0db1a5bdfcee0dbfa89607672598ae203c9045 upstream. |
| |
| Performing the following task with kmemleak enabled: |
| |
| # cd /sys/kernel/tracing/events/irq/irq_handler_entry/ |
| # echo 'enable_event:kmem:kmalloc:3 if irq >' > trigger |
| # echo 'enable_event:kmem:kmalloc:3 if irq > 31' > trigger |
| # echo scan > /sys/kernel/debug/kmemleak |
| # cat /sys/kernel/debug/kmemleak |
| unreferenced object 0xffff8800b9290308 (size 32): |
| comm "bash", pid 1114, jiffies 4294848451 (age 141.139s) |
| hex dump (first 32 bytes): |
| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
| backtrace: |
| [<ffffffff81cef5aa>] kmemleak_alloc+0x4a/0xa0 |
| [<ffffffff81357938>] kmem_cache_alloc_trace+0x158/0x290 |
| [<ffffffff81261c09>] create_filter_start.constprop.28+0x99/0x940 |
| [<ffffffff812639c9>] create_filter+0xa9/0x160 |
| [<ffffffff81263bdc>] create_event_filter+0xc/0x10 |
| [<ffffffff812655e5>] set_trigger_filter+0xe5/0x210 |
| [<ffffffff812660c4>] event_enable_trigger_func+0x324/0x490 |
| [<ffffffff812652e2>] event_trigger_write+0x1a2/0x260 |
| [<ffffffff8138cf87>] __vfs_write+0xd7/0x380 |
| [<ffffffff8138f421>] vfs_write+0x101/0x260 |
| [<ffffffff8139187b>] SyS_write+0xab/0x130 |
| [<ffffffff81cfd501>] entry_SYSCALL_64_fastpath+0x1f/0xbe |
| [<ffffffffffffffff>] 0xffffffffffffffff |
| |
| The function create_filter() is passed a 'filterp' pointer that gets |
| allocated, and if "set_str" is true, it is up to the caller to free it, even |
| on error. The problem is that the pointer is not freed by create_filter() |
| when set_str is false. This is a bug, and it is not up to the caller to free |
| the filter on error if it doesn't care about the string. |
| |
| Link: http://lkml.kernel.org/r/1502705898-27571-2-git-send-email-chuhu@redhat.com |
| |
| Fixes: 38b78eb85 ("tracing: Factorize filter creation") |
| Reported-by: Chunyu Hu <chuhu@redhat.com> |
| Tested-by: Chunyu Hu <chuhu@redhat.com> |
| Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| kernel/trace/trace_events_filter.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/kernel/trace/trace_events_filter.c |
| +++ b/kernel/trace/trace_events_filter.c |
| @@ -1909,6 +1909,10 @@ static int create_filter(struct ftrace_e |
| if (err && set_str) |
| append_filter_err(ps, filter); |
| } |
| + if (err && !set_str) { |
| + free_event_filter(filter); |
| + filter = NULL; |
| + } |
| create_filter_finish(ps); |
| |
| *filterp = filter; |