lkml.org 
[lkml]   [2022]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6.0 721/862] bpf: Adjust kprobe_multi entry_ip for CONFIG_X86_KERNEL_IBT
    Date
    From: Jiri Olsa <jolsa@kernel.org>

    [ Upstream commit c09eb2e578eb1668bbc84dc07e8d8bd6f04b9a02 ]

    Martynas reported bpf_get_func_ip returning +4 address when
    CONFIG_X86_KERNEL_IBT option is enabled.

    When CONFIG_X86_KERNEL_IBT is enabled we'll have endbr instruction
    at the function entry, which screws return value of bpf_get_func_ip()
    helper that should return the function address.

    There's short term workaround for kprobe_multi bpf program made by
    Alexei [1], but we need this fixup also for bpf_get_attach_cookie,
    that returns cookie based on the entry_ip value.

    Moving the fixup in the fprobe handler, so both bpf_get_func_ip
    and bpf_get_attach_cookie get expected function address when
    CONFIG_X86_KERNEL_IBT option is enabled.

    Also renaming kprobe_multi_link_handler entry_ip argument to fentry_ip
    so it's clearer this is an ftrace __fentry__ ip.

    [1] commit 7f0059b58f02 ("selftests/bpf: Fix kprobe_multi test.")

    Cc: Peter Zijlstra <peterz@infradead.org>
    Reported-by: Martynas Pumputis <m@lambda.lt>
    Acked-by: Andrii Nakryiko <andrii@kernel.org>
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    Link: https://lore.kernel.org/r/20220926153340.1621984-5-jolsa@kernel.org
    Signed-off-by: Alexei Starovoitov <ast@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    kernel/trace/bpf_trace.c | 20 +++++++++++++++++--
    .../selftests/bpf/progs/kprobe_multi.c | 4 +---
    2 files changed, 19 insertions(+), 5 deletions(-)

    diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
    index 68e5cdd24cef..b1daf7c9b895 100644
    --- a/kernel/trace/bpf_trace.c
    +++ b/kernel/trace/bpf_trace.c
    @@ -1026,6 +1026,22 @@ static const struct bpf_func_proto bpf_get_func_ip_proto_tracing = {
    .arg1_type = ARG_PTR_TO_CTX,
    };

    +#ifdef CONFIG_X86_KERNEL_IBT
    +static unsigned long get_entry_ip(unsigned long fentry_ip)
    +{
    + u32 instr;
    +
    + /* Being extra safe in here in case entry ip is on the page-edge. */
    + if (get_kernel_nofault(instr, (u32 *) fentry_ip - 1))
    + return fentry_ip;
    + if (is_endbr(instr))
    + fentry_ip -= ENDBR_INSN_SIZE;
    + return fentry_ip;
    +}
    +#else
    +#define get_entry_ip(fentry_ip) fentry_ip
    +#endif
    +
    BPF_CALL_1(bpf_get_func_ip_kprobe, struct pt_regs *, regs)
    {
    struct kprobe *kp = kprobe_running();
    @@ -2414,13 +2430,13 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link,
    }

    static void
    -kprobe_multi_link_handler(struct fprobe *fp, unsigned long entry_ip,
    +kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,
    struct pt_regs *regs)
    {
    struct bpf_kprobe_multi_link *link;

    link = container_of(fp, struct bpf_kprobe_multi_link, fp);
    - kprobe_multi_link_prog_run(link, entry_ip, regs);
    + kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs);
    }

    static int symbols_cmp_r(const void *a, const void *b, const void *priv)
    diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi.c b/tools/testing/selftests/bpf/progs/kprobe_multi.c
    index 08f95a8155d1..98c3399e15c0 100644
    --- a/tools/testing/selftests/bpf/progs/kprobe_multi.c
    +++ b/tools/testing/selftests/bpf/progs/kprobe_multi.c
    @@ -36,15 +36,13 @@ __u64 kretprobe_test6_result = 0;
    __u64 kretprobe_test7_result = 0;
    __u64 kretprobe_test8_result = 0;

    -extern bool CONFIG_X86_KERNEL_IBT __kconfig __weak;
    -
    static void kprobe_multi_check(void *ctx, bool is_return)
    {
    if (bpf_get_current_pid_tgid() >> 32 != pid)
    return;

    __u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;
    - __u64 addr = bpf_get_func_ip(ctx) - (CONFIG_X86_KERNEL_IBT ? 4 : 0);
    + __u64 addr = bpf_get_func_ip(ctx);

    #define SET(__var, __addr, __cookie) ({ \
    if (((const void *) addr == __addr) && \
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-10-19 13:12    [W:4.023 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site