lkml.org 
[lkml]   [2019]   [Oct]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] tracing/kprobe: Check whether the non-suffixed symbol is notrace
    Date
    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().

    Fixes: 45408c4f9250 ("tracing: kprobes: Prohibit probing on notrace function")
    Signed-off-by: Masami Hiramatsu <mhiramat@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 1552a95c743b..7f890262c8a3 100644
    --- a/kernel/trace/trace_kprobe.c
    +++ b/kernel/trace/trace_kprobe.c
    @@ -435,11 +435,10 @@ static int disable_trace_kprobe(struct trace_event_call *call,

    #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;

    @@ -452,6 +451,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
    \
     
     \ /
      Last update: 2019-10-29 09:32    [W:3.282 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site