From 99045ce3b8fe153e4b93e82bffdd7f0a9628613c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 28 Jul 2018 10:09:39 +0200 Subject: [PATCH] 3.18-stable patches added patches: tracing-fix-double-free-of-event_trigger_data.patch tracing-fix-possible-double-free-in-event_enable_trigger_func.patch tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe-failure.patch tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch --- queue-3.18/series | 4 + ...ix-double-free-of-event_trigger_data.patch | 112 ++++++++++++++++++ ...le-free-in-event_enable_trigger_func.patch | 60 ++++++++++ ...flags-on-enable_trace_kprobe-failure.patch | 63 ++++++++++ ...ing-about-maybe-unused-link-variable.patch | 53 +++++++++ 5 files changed, 292 insertions(+) create mode 100644 queue-3.18/tracing-fix-double-free-of-event_trigger_data.patch create mode 100644 queue-3.18/tracing-fix-possible-double-free-in-event_enable_trigger_func.patch create mode 100644 queue-3.18/tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe-failure.patch create mode 100644 queue-3.18/tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch diff --git a/queue-3.18/series b/queue-3.18/series index e69de29bb2d..1d7c9ad17b5 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -0,0 +1,4 @@ +tracing-fix-double-free-of-event_trigger_data.patch +tracing-fix-possible-double-free-in-event_enable_trigger_func.patch +tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe-failure.patch +tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch diff --git a/queue-3.18/tracing-fix-double-free-of-event_trigger_data.patch b/queue-3.18/tracing-fix-double-free-of-event_trigger_data.patch new file mode 100644 index 00000000000..bc3dcf2c636 --- /dev/null +++ b/queue-3.18/tracing-fix-double-free-of-event_trigger_data.patch @@ -0,0 +1,112 @@ +From 1863c387259b629e4ebfb255495f67cd06aa229b Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Tue, 24 Jul 2018 19:13:31 -0400 +Subject: tracing: Fix double free of event_trigger_data + +From: Steven Rostedt (VMware) + +commit 1863c387259b629e4ebfb255495f67cd06aa229b upstream. + +Running the following: + + # cd /sys/kernel/debug/tracing + # echo 500000 > buffer_size_kb +[ Or some other number that takes up most of memory ] + # echo snapshot > events/sched/sched_switch/trigger + +Triggers the following bug: + + ------------[ cut here ]------------ + kernel BUG at mm/slub.c:296! + invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC PTI + CPU: 6 PID: 6878 Comm: bash Not tainted 4.18.0-rc6-test+ #1066 + Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016 + RIP: 0010:kfree+0x16c/0x180 + Code: 05 41 0f b6 72 51 5b 5d 41 5c 4c 89 d7 e9 ac b3 f8 ff 48 89 d9 48 89 da 41 b8 01 00 00 00 5b 5d 41 5c 4c 89 d6 e9 f4 f3 ff ff <0f> 0b 0f 0b 48 8b 3d d9 d8 f9 00 e9 c1 fe ff ff 0f 1f 40 00 0f 1f + RSP: 0018:ffffb654436d3d88 EFLAGS: 00010246 + RAX: ffff91a9d50f3d80 RBX: ffff91a9d50f3d80 RCX: ffff91a9d50f3d80 + RDX: 00000000000006a4 RSI: ffff91a9de5a60e0 RDI: ffff91a9d9803500 + RBP: ffffffff8d267c80 R08: 00000000000260e0 R09: ffffffff8c1a56be + R10: fffff0d404543cc0 R11: 0000000000000389 R12: ffffffff8c1a56be + R13: ffff91a9d9930e18 R14: ffff91a98c0c2890 R15: ffffffff8d267d00 + FS: 00007f363ea64700(0000) GS:ffff91a9de580000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 000055c1cacc8e10 CR3: 00000000d9b46003 CR4: 00000000001606e0 + Call Trace: + event_trigger_callback+0xee/0x1d0 + event_trigger_write+0xfc/0x1a0 + __vfs_write+0x33/0x190 + ? handle_mm_fault+0x115/0x230 + ? _cond_resched+0x16/0x40 + vfs_write+0xb0/0x190 + ksys_write+0x52/0xc0 + do_syscall_64+0x5a/0x160 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + RIP: 0033:0x7f363e16ab50 + Code: 73 01 c3 48 8b 0d 38 83 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 79 db 2c 00 00 75 10 b8 01 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 1e e3 01 00 48 89 04 24 + RSP: 002b:00007fff9a4c6378 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 + RAX: ffffffffffffffda RBX: 0000000000000009 RCX: 00007f363e16ab50 + RDX: 0000000000000009 RSI: 000055c1cacc8e10 RDI: 0000000000000001 + RBP: 000055c1cacc8e10 R08: 00007f363e435740 R09: 00007f363ea64700 + R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000000009 + R13: 0000000000000001 R14: 00007f363e4345e0 R15: 00007f363e4303c0 + Modules linked in: ip6table_filter ip6_tables snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_seq snd_seq_device i915 snd_pcm snd_timer i2c_i801 snd soundcore i2c_algo_bit drm_kms_helper +86_pkg_temp_thermal video kvm_intel kvm irqbypass wmi e1000e + ---[ end trace d301afa879ddfa25 ]--- + +The cause is because the register_snapshot_trigger() call failed to +allocate the snapshot buffer, and then called unregister_trigger() +which freed the data that was passed to it. Then on return to the +function that called register_snapshot_trigger(), as it sees it +failed to register, it frees the trigger_data again and causes +a double free. + +By calling event_trigger_init() on the trigger_data (which only ups +the reference counter for it), and then event_trigger_free() afterward, +the trigger_data would not get freed by the registering trigger function +as it would only up and lower the ref count for it. If the register +trigger function fails, then the event_trigger_free() called after it +will free the trigger data normally. + +Link: http://lkml.kernel.org/r/20180724191331.738eb819@gandalf.local.home + +Cc: stable@vger.kerne.org +Fixes: 93e31ffbf417 ("tracing: Add 'snapshot' event trigger command") +Reported-by: Masami Hiramatsu +Reviewed-by: Masami Hiramatsu +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_events_trigger.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/kernel/trace/trace_events_trigger.c ++++ b/kernel/trace/trace_events_trigger.c +@@ -663,6 +663,8 @@ event_trigger_callback(struct event_comm + goto out_free; + + out_reg: ++ /* Up the trigger_data count to make sure reg doesn't free it on failure */ ++ event_trigger_init(trigger_ops, trigger_data); + ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file); + /* + * The above returns on success the # of functions enabled, +@@ -670,11 +672,13 @@ event_trigger_callback(struct event_comm + * Consider no functions a failure too. + */ + if (!ret) { ++ cmd_ops->unreg(glob, trigger_ops, trigger_data, file); + ret = -ENOENT; +- goto out_free; +- } else if (ret < 0) +- goto out_free; +- ret = 0; ++ } else if (ret > 0) ++ ret = 0; ++ ++ /* Down the counter of trigger_data or free it if not used anymore */ ++ event_trigger_free(trigger_ops, trigger_data); + out: + return ret; + diff --git a/queue-3.18/tracing-fix-possible-double-free-in-event_enable_trigger_func.patch b/queue-3.18/tracing-fix-possible-double-free-in-event_enable_trigger_func.patch new file mode 100644 index 00000000000..fae343f77e6 --- /dev/null +++ b/queue-3.18/tracing-fix-possible-double-free-in-event_enable_trigger_func.patch @@ -0,0 +1,60 @@ +From 15cc78644d0075e76d59476a4467e7143860f660 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Wed, 25 Jul 2018 16:02:06 -0400 +Subject: tracing: Fix possible double free in event_enable_trigger_func() + +From: Steven Rostedt (VMware) + +commit 15cc78644d0075e76d59476a4467e7143860f660 upstream. + +There was a case that triggered a double free in event_trigger_callback() +due to the called reg() function freeing the trigger_data and then it +getting freed again by the error return by the caller. The solution there +was to up the trigger_data ref count. + +Code inspection found that event_enable_trigger_func() has the same issue, +but is not as easy to trigger (requires harder to trigger failures). It +needs to be solved slightly different as it needs more to clean up when the +reg() function fails. + +Link: http://lkml.kernel.org/r/20180725124008.7008e586@gandalf.local.home + +Cc: stable@vger.kernel.org +Fixes: 7862ad1846e99 ("tracing: Add 'enable_event' and 'disable_event' event trigger commands") +Reivewed-by: Masami Hiramatsu +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_events_trigger.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace_events_trigger.c ++++ b/kernel/trace/trace_events_trigger.c +@@ -1231,6 +1231,9 @@ event_enable_trigger_func(struct event_c + goto out; + } + ++ /* Up the trigger_data count to make sure nothing frees it on failure */ ++ event_trigger_init(trigger_ops, trigger_data); ++ + if (trigger) { + number = strsep(&trigger, ":"); + +@@ -1281,6 +1284,7 @@ event_enable_trigger_func(struct event_c + goto out_disable; + /* Just return zero, not the number of enabled functions */ + ret = 0; ++ event_trigger_free(trigger_ops, trigger_data); + out: + return ret; + +@@ -1291,7 +1295,7 @@ event_enable_trigger_func(struct event_c + out_free: + if (cmd_ops->set_filter) + cmd_ops->set_filter(NULL, trigger_data, NULL); +- kfree(trigger_data); ++ event_trigger_free(trigger_ops, trigger_data); + kfree(enable_data); + goto out; + } diff --git a/queue-3.18/tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe-failure.patch b/queue-3.18/tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe-failure.patch new file mode 100644 index 00000000000..833ee98b501 --- /dev/null +++ b/queue-3.18/tracing-kprobes-fix-trace_probe-flags-on-enable_trace_kprobe-failure.patch @@ -0,0 +1,63 @@ +From 57ea2a34adf40f3a6e88409aafcf803b8945619a Mon Sep 17 00:00:00 2001 +From: Artem Savkov +Date: Wed, 25 Jul 2018 16:20:38 +0200 +Subject: tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure + +From: Artem Savkov + +commit 57ea2a34adf40f3a6e88409aafcf803b8945619a upstream. + +If enable_trace_kprobe fails to enable the probe in enable_k(ret)probe +it returns an error, but does not unset the tp flags it set previously. +This results in a probe being considered enabled and failures like being +unable to remove the probe through kprobe_events file since probes_open() +expects every probe to be disabled. + +Link: http://lkml.kernel.org/r/20180725102826.8300-1-asavkov@redhat.com +Link: http://lkml.kernel.org/r/20180725142038.4765-1-asavkov@redhat.com + +Cc: Ingo Molnar +Cc: stable@vger.kernel.org +Fixes: 41a7dd420c57 ("tracing/kprobes: Support ftrace_event_file base multibuffer") +Acked-by: Masami Hiramatsu +Reviewed-by: Josh Poimboeuf +Signed-off-by: Artem Savkov +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_kprobe.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -361,11 +361,10 @@ static struct trace_kprobe *find_trace_k + static int + enable_trace_kprobe(struct trace_kprobe *tk, struct ftrace_event_file *file) + { ++ struct event_file_link *link; + int ret = 0; + + if (file) { +- struct event_file_link *link; +- + link = kmalloc(sizeof(*link), GFP_KERNEL); + if (!link) { + ret = -ENOMEM; +@@ -385,6 +384,16 @@ enable_trace_kprobe(struct trace_kprobe + else + ret = enable_kprobe(&tk->rp.kp); + } ++ ++ if (ret) { ++ if (file) { ++ list_del_rcu(&link->list); ++ kfree(link); ++ tk->tp.flags &= ~TP_FLAG_TRACE; ++ } else { ++ tk->tp.flags &= ~TP_FLAG_PROFILE; ++ } ++ } + out: + return ret; + } diff --git a/queue-3.18/tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch b/queue-3.18/tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch new file mode 100644 index 00000000000..f9a697a2c92 --- /dev/null +++ b/queue-3.18/tracing-quiet-gcc-warning-about-maybe-unused-link-variable.patch @@ -0,0 +1,53 @@ +From 2519c1bbe38d7acacc9aacba303ca6f97482ed53 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Wed, 25 Jul 2018 22:28:56 -0400 +Subject: tracing: Quiet gcc warning about maybe unused link variable + +From: Steven Rostedt (VMware) + +commit 2519c1bbe38d7acacc9aacba303ca6f97482ed53 upstream. + +Commit 57ea2a34adf4 ("tracing/kprobes: Fix trace_probe flags on +enable_trace_kprobe() failure") added an if statement that depends on another +if statement that gcc doesn't see will initialize the "link" variable and +gives the warning: + + "warning: 'link' may be used uninitialized in this function" + +It is really a false positive, but to quiet the warning, and also to make +sure that it never actually is used uninitialized, initialize the "link" +variable to NULL and add an if (!WARN_ON_ONCE(!link)) where the compiler +thinks it could be used uninitialized. + +Cc: stable@vger.kernel.org +Fixes: 57ea2a34adf4 ("tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure") +Reported-by: kbuild test robot +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_kprobe.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -361,7 +361,7 @@ static struct trace_kprobe *find_trace_k + static int + enable_trace_kprobe(struct trace_kprobe *tk, struct ftrace_event_file *file) + { +- struct event_file_link *link; ++ struct event_file_link *link = NULL; + int ret = 0; + + if (file) { +@@ -387,7 +387,9 @@ enable_trace_kprobe(struct trace_kprobe + + if (ret) { + if (file) { +- list_del_rcu(&link->list); ++ /* Notice the if is true on not WARN() */ ++ if (!WARN_ON_ONCE(!link)) ++ list_del_rcu(&link->list); + kfree(link); + tk->tp.flags &= ~TP_FLAG_TRACE; + } else { -- 2.47.3