bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrii Nakryiko <andrii.nakryiko@gmail.com>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ingo Molnar <mingo@kernel.org>, X86 ML <x86@kernel.org>,
	Daniel Xu <dxu@dxuuu.xyz>,
	open list <linux-kernel@vger.kernel.org>,
	bpf <bpf@vger.kernel.org>, Jakub Kicinski <kuba@kernel.org>,
	Ingo Molnar <mingo@redhat.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Kernel Team <kernel-team@fb.com>, Yonghong Song <yhs@fb.com>
Subject: Re: [PATCH -tip v2 00/10] kprobes: Fix stacktrace with kretprobes
Date: Mon, 17 May 2021 14:06:24 -0700	[thread overview]
Message-ID: <CAEf4Bzb46223OxVJeydhhKJVLbWjWiAEXbFZ7yb7=R3D_1y0vQ@mail.gmail.com> (raw)
In-Reply-To: <20210316153022.70cc181a2b3e0f73923e54da@kernel.org>

On Tue, Mar 16, 2021 at 1:45 AM Masami Hiramatsu <mhiramat@kernel.org> wrote:
>
> On Mon, 15 Mar 2021 21:30:03 -0500
> Josh Poimboeuf <jpoimboe@redhat.com> wrote:
>
> > On Fri, Mar 12, 2021 at 03:41:44PM +0900, Masami Hiramatsu wrote:
> > > Hello,
> > >
> > > Here is the 2nd version of the series to fix the stacktrace with kretprobe.
> > >
> > > The 1st series is here;
> > >
> > > https://lore.kernel.org/bpf/161495873696.346821.10161501768906432924.stgit@devnote2/
> > >
> > > In this version I merged the ORC unwinder fix for kretprobe which discussed in the
> > > previous thread. [3/10] is updated according to the Miroslav's comment. [4/10] is
> > > updated for simplify the code. [5/10]-[9/10] are discussed in the previsous tread
> > > and are introduced to the series.
> > >
> > > Daniel, can you also test this again? I and Josh discussed a bit different
> > > method and I've implemented it on this version.
> > >
> > > This actually changes the kretprobe behavisor a bit, now the instraction pointer in
> > > the pt_regs passed to kretprobe user handler is correctly set the real return
> > > address. So user handlers can get it via instruction_pointer() API.
> >
> > When I add WARN_ON(1) to a test kretprobe, it doesn't unwind properly.
> >
> > show_trace_log_lvl() reads the entire stack in lockstep with calls to
> > the unwinder so that it can decide which addresses get prefixed with
> > '?'.  So it expects to find an actual return address on the stack.
> > Instead it finds %rsp.  So it never syncs up with unwind_next_frame()
> > and shows all remaining addresses as unreliable.
> >
> >   Call Trace:
> >    __kretprobe_trampoline_handler+0xca/0x1a0
> >    trampoline_handler+0x3d/0x50
> >    kretprobe_trampoline+0x25/0x50
> >    ? init_test_probes.cold+0x323/0x387
> >    ? init_kprobes+0x144/0x14c
> >    ? init_optprobes+0x15/0x15
> >    ? do_one_initcall+0x5b/0x300
> >    ? lock_is_held_type+0xe8/0x140
> >    ? kernel_init_freeable+0x174/0x2cd
> >    ? rest_init+0x233/0x233
> >    ? kernel_init+0xa/0x11d
> >    ? ret_from_fork+0x22/0x30
> >
> > How about pushing 'kretprobe_trampoline' instead of %rsp for the return
> > address placeholder.  That fixes the above test, and removes the need
> > for the weird 'state->ip == sp' check:
> >
> >   Call Trace:
> >    __kretprobe_trampoline_handler+0xca/0x150
> >    trampoline_handler+0x3d/0x50
> >    kretprobe_trampoline+0x29/0x50
> >    ? init_test_probes.cold+0x323/0x387
> >    elfcorehdr_read+0x10/0x10
> >    init_kprobes+0x144/0x14c
> >    ? init_optprobes+0x15/0x15
> >    do_one_initcall+0x72/0x280
> >    kernel_init_freeable+0x174/0x2cd
> >    ? rest_init+0x122/0x122
> >    kernel_init+0xa/0x10e
> >    ret_from_fork+0x22/0x30
> >
> > Though, init_test_probes.cold() (the real return address) is still
> > listed as unreliable.  Maybe we need a call to kretprobe_find_ret_addr()
> > in show_trace_log_lvl(), similar to the ftrace_graph_ret_addr() call
> > there.
>
> Thanks for the test!
> OK, that could be acceptable. However, push %sp still needed for accessing
> stack address from kretprobe handler via pt_regs. (regs->sp must point
> the stack address)
> Anyway, with int3, it pushes one more entry for emulating call, so I think
> it is OK.
> Let me update the series!
>

Hi Misami,

Did you get a chance to follow up on this? I checked v5.13-rc1 and it
still has this issue. Inability to capture a stack trace from BPF
kretprobes is a pretty big problem for some applications, it would be
great to get this fixed. Thanks!


> Thank you!
>
> >
> >
> >
> > diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
> > index 06f33bfebc50..70188fdd288e 100644
> > --- a/arch/x86/kernel/kprobes/core.c
> > +++ b/arch/x86/kernel/kprobes/core.c
> > @@ -766,19 +766,19 @@ asm(
> >       "kretprobe_trampoline:\n"
> >       /* We don't bother saving the ss register */
> >  #ifdef CONFIG_X86_64
> > -     "       pushq %rsp\n"
> > +     /* Push fake return address to tell the unwinder it's a kretprobe */
> > +     "       pushq $kretprobe_trampoline\n"
> >       UNWIND_HINT_FUNC
> >       "       pushfq\n"
> >       SAVE_REGS_STRING
> >       "       movq %rsp, %rdi\n"
> >       "       call trampoline_handler\n"
> > -     /* Replace saved sp with true return address. */
> > +     /* Replace the fake return address with the real one. */
> >       "       movq %rax, 19*8(%rsp)\n"
> >       RESTORE_REGS_STRING
> >       "       popfq\n"
> >  #else
> >       "       pushl %esp\n"
> > -     UNWIND_HINT_FUNC
> >       "       pushfl\n"
> >       SAVE_REGS_STRING
> >       "       movl %esp, %eax\n"
> > diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
> > index 1d1b9388a1b1..1d3de84d2410 100644
> > --- a/arch/x86/kernel/unwind_orc.c
> > +++ b/arch/x86/kernel/unwind_orc.c
> > @@ -548,8 +548,7 @@ bool unwind_next_frame(struct unwind_state *state)
> >                * In those cases, find the correct return address from
> >                * task->kretprobe_instances list.
> >                */
> > -             if (state->ip == sp ||
> > -                 is_kretprobe_trampoline(state->ip))
> > +             if (is_kretprobe_trampoline(state->ip))
> >                       state->ip = kretprobe_find_ret_addr(state->task,
> >                                                           &state->kr_iter);
> >
> >
> >
>
>
> --
> Masami Hiramatsu <mhiramat@kernel.org>

  reply	other threads:[~2021-05-17 21:06 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-12  6:41 [PATCH -tip v2 00/10] kprobes: Fix stacktrace with kretprobes Masami Hiramatsu
2021-03-12  6:41 ` [PATCH -tip v2 01/10] ia64: kprobes: Fix to pass correct trampoline address to the handler Masami Hiramatsu
2021-03-12  6:42 ` [PATCH -tip v2 02/10] kprobes: treewide: Replace arch_deref_entry_point() with dereference_function_descriptor() Masami Hiramatsu
2021-05-24  9:26   ` Naveen N. Rao
2021-05-24 23:41     ` Masami Hiramatsu
2021-03-12  6:42 ` [PATCH -tip v2 03/10] kprobes: treewide: Remove trampoline_address from kretprobe_trampoline_handler() Masami Hiramatsu
2021-03-12  6:42 ` [PATCH -tip v2 04/10] kprobes: stacktrace: Recover the address changed by kretprobe Masami Hiramatsu
2021-03-17  0:27   ` Masami Hiramatsu
2021-03-12  6:42 ` [PATCH -tip v2 05/10] x86/kprobes: Add UNWIND_HINT_FUNC on kretprobe_trampoline code Masami Hiramatsu
2021-03-12  6:42 ` [PATCH -tip v2 06/10] ARC: Add instruction_pointer_set() API Masami Hiramatsu
2021-03-12  6:43 ` [PATCH -tip v2 07/10] ia64: " Masami Hiramatsu
2021-03-12  6:43 ` [PATCH -tip v2 08/10] kprobes: Setup instruction pointer in __kretprobe_trampoline_handler Masami Hiramatsu
2021-03-12  6:43 ` [PATCH -tip v2 09/10] x86/unwind/orc: Fixup kretprobe trampoline entry Masami Hiramatsu
2021-03-12  6:43 ` [PATCH -tip v2 10/10] tracing: Remove kretprobe unknown indicator from stacktrace Masami Hiramatsu
2021-03-12 18:56 ` [PATCH -tip v2 00/10] kprobes: Fix stacktrace with kretprobes Daniel Xu
2021-03-16  2:30 ` Josh Poimboeuf
2021-03-16  6:30   ` Masami Hiramatsu
2021-05-17 21:06     ` Andrii Nakryiko [this message]
2021-05-23 14:22       ` Masami Hiramatsu
2021-05-24 17:49         ` Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAEf4Bzb46223OxVJeydhhKJVLbWjWiAEXbFZ7yb7=R3D_1y0vQ@mail.gmail.com' \
    --to=andrii.nakryiko@gmail.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=dxu@dxuuu.xyz \
    --cc=jpoimboe@redhat.com \
    --cc=kernel-team@fb.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=mingo@redhat.com \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).