| From b97635cc787efda0c261b76ea69c8e274ce2d8ed Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 29 Oct 2019 17:31:44 +0900 |
| Subject: tracing/kprobe: Check whether the non-suffixed symbol is notrace |
| |
| From: Masami Hiramatsu <mhiramat@kernel.org> |
| |
| [ Upstream commit c7411a1a126f649be71526a36d4afac9e5aefa13 ] |
| |
| Check whether the non-suffixed symbol is notrace, since suffixed |
| symbols are generated by the compilers for optimization. Based on |
| these suffixed symbols, notrace check might not work because |
| some of them are just a partial code of the original function. |
| (e.g. cold-cache (unlikely) code is separated from original |
| function as FUNCTION.cold.XX) |
| |
| For example, without this fix, |
| # echo p device_add.cold.67 > /sys/kernel/debug/tracing/kprobe_events |
| sh: write error: Invalid argument |
| |
| # cat /sys/kernel/debug/tracing/error_log |
| [ 135.491035] trace_kprobe: error: Failed to register probe event |
| Command: p device_add.cold.67 |
| ^ |
| # dmesg | tail -n 1 |
| [ 135.488599] trace_kprobe: Could not probe notrace function device_add.cold.67 |
| |
| With this, |
| # echo p device_add.cold.66 > /sys/kernel/debug/tracing/kprobe_events |
| # cat /sys/kernel/debug/kprobes/list |
| ffffffff81599de9 k device_add.cold.66+0x0 [DISABLED] |
| |
| Actually, kprobe blacklist already did similar thing, |
| see within_kprobe_blacklist(). |
| |
| Link: http://lkml.kernel.org/r/157233790394.6706.18243942030937189679.stgit@devnote2 |
| |
| Fixes: 45408c4f9250 ("tracing: kprobes: Prohibit probing on notrace function") |
| Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| kernel/trace/trace_kprobe.c | 27 ++++++++++++++++++++++++--- |
| 1 file changed, 24 insertions(+), 3 deletions(-) |
| |
| diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c |
| index f9a0cd094b81..c61b2b0a99e9 100644 |
| --- a/kernel/trace/trace_kprobe.c |
| +++ b/kernel/trace/trace_kprobe.c |
| @@ -519,11 +519,10 @@ disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file) |
| |
| #if defined(CONFIG_KPROBES_ON_FTRACE) && \ |
| !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE) |
| -static bool within_notrace_func(struct trace_kprobe *tk) |
| +static bool __within_notrace_func(unsigned long addr) |
| { |
| - unsigned long offset, size, addr; |
| + unsigned long offset, size; |
| |
| - addr = trace_kprobe_address(tk); |
| if (!addr || !kallsyms_lookup_size_offset(addr, &size, &offset)) |
| return false; |
| |
| @@ -536,6 +535,28 @@ static bool within_notrace_func(struct trace_kprobe *tk) |
| */ |
| return !ftrace_location_range(addr, addr + size - 1); |
| } |
| + |
| +static bool within_notrace_func(struct trace_kprobe *tk) |
| +{ |
| + unsigned long addr = addr = trace_kprobe_address(tk); |
| + char symname[KSYM_NAME_LEN], *p; |
| + |
| + if (!__within_notrace_func(addr)) |
| + return false; |
| + |
| + /* Check if the address is on a suffixed-symbol */ |
| + if (!lookup_symbol_name(addr, symname)) { |
| + p = strchr(symname, '.'); |
| + if (!p) |
| + return true; |
| + *p = '\0'; |
| + addr = (unsigned long)kprobe_lookup_name(symname, 0); |
| + if (addr) |
| + return __within_notrace_func(addr); |
| + } |
| + |
| + return true; |
| +} |
| #else |
| #define within_notrace_func(tk) (false) |
| #endif |
| -- |
| 2.20.1 |
| |