diff options
author | Alexei Starovoitov <ast@kernel.org> | 2022-09-26 20:30:40 -0700 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2022-09-26 20:31:02 -0700 |
commit | 30b8fdbbe31b2422f46fcd6d3960e563affe76d7 (patch) | |
tree | 4257dcd090e4aa3d9c55551abd6762aa9fdff21a /kernel/trace/bpf_trace.c | |
parent | bec217197b412d74168c6a42fc0f76d0cc9cad00 (diff) | |
parent | 738c345b74b8d11edd01b6cee5628c6b8368d8ea (diff) |
Merge branch 'bpf: Fixes for CONFIG_X86_KERNEL_IBT'
Jiri Olsa says:
====================
Martynas reported bpf_get_func_ip returning +4 address when
CONFIG_X86_KERNEL_IBT option is enabled and I found there are
some failing bpf tests when this option is enabled.
The CONFIG_X86_KERNEL_IBT option adds endbr instruction at the
function entry, so the idea is to 'fix' entry ip for kprobe_multi
and trampoline probes, because they are placed on the function
entry.
v5 changes:
- updated uapi/linux/bpf.h headers with comment for
bpf_get_func_ip returning 0 [Andrii]
- added acks
v4 changes:
- used get_kernel_nofault to read previous instruction [Peter]
- used movabs instruction in trampoline comment [Peter]
- renamed fentry_ip argument in kprobe_multi_link_handler [Peter]
v3 changes:
- using 'unused' bpf function to get IBT config option
into selftest skeleton
- rebased to current bpf-next/master
- added ack/review from Masami
v2 changes:
- change kprobes get_func_ip to return zero for kprobes
attached within the function body [Andrii]
- detect IBT config and properly test kprobe with offset
[Andrii]
v1 changes:
- read previous instruction in kprobe_multi link handler
and adjust entry_ip for CONFIG_X86_KERNEL_IBT option
- split first patch into 2 separate changes
- update changelogs
====================
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel/trace/bpf_trace.c')
-rw-r--r-- | kernel/trace/bpf_trace.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index b05f0310dbd3..688552df95ca 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1028,11 +1028,30 @@ 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(); - return kp ? (uintptr_t)kp->addr : 0; + if (!kp || !(kp->flags & KPROBE_FLAG_ON_FUNC_ENTRY)) + return 0; + + return get_entry_ip((uintptr_t)kp->addr); } static const struct bpf_func_proto bpf_get_func_ip_proto_kprobe = { @@ -2600,13 +2619,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) |