| From 6c14133d2d3f768e0a35128faac8aa6ed4815051 Mon Sep 17 00:00:00 2001 |
| From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> |
| Date: Mon, 7 Jun 2021 21:39:08 -0400 |
| Subject: ftrace: Do not blindly read the ip address in ftrace_bug() |
| |
| From: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| |
| commit 6c14133d2d3f768e0a35128faac8aa6ed4815051 upstream. |
| |
| It was reported that a bug on arm64 caused a bad ip address to be used for |
| updating into a nop in ftrace_init(), but the error path (rightfully) |
| returned -EINVAL and not -EFAULT, as the bug caused more than one error to |
| occur. But because -EINVAL was returned, the ftrace_bug() tried to report |
| what was at the location of the ip address, and read it directly. This |
| caused the machine to panic, as the ip was not pointing to a valid memory |
| address. |
| |
| Instead, read the ip address with copy_from_kernel_nofault() to safely |
| access the memory, and if it faults, report that the address faulted, |
| otherwise report what was in that location. |
| |
| Link: https://lore.kernel.org/lkml/20210607032329.28671-1-mark-pk.tsai@mediatek.com/ |
| |
| Cc: stable@vger.kernel.org |
| Fixes: 05736a427f7e1 ("ftrace: warn on failure to disable mcount callers") |
| Reported-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com> |
| Tested-by: Mark-PK Tsai <mark-pk.tsai@mediatek.com> |
| Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/trace/ftrace.c | 8 +++++++- |
| 1 file changed, 7 insertions(+), 1 deletion(-) |
| |
| --- a/kernel/trace/ftrace.c |
| +++ b/kernel/trace/ftrace.c |
| @@ -1961,12 +1961,18 @@ static int ftrace_hash_ipmodify_update(s |
| |
| static void print_ip_ins(const char *fmt, const unsigned char *p) |
| { |
| + char ins[MCOUNT_INSN_SIZE]; |
| int i; |
| |
| + if (probe_kernel_read(ins, p, MCOUNT_INSN_SIZE)) { |
| + printk(KERN_CONT "%s[FAULT] %px\n", fmt, p); |
| + return; |
| + } |
| + |
| printk(KERN_CONT "%s", fmt); |
| |
| for (i = 0; i < MCOUNT_INSN_SIZE; i++) |
| - printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); |
| + printk(KERN_CONT "%s%02x", i ? ":" : "", ins[i]); |
| } |
| |
| enum ftrace_bug_type ftrace_bug_type; |