From: Jiri Olsa <olsajiri@gmail.com>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Jiri Olsa <olsajiri@gmail.com>,
Steven Rostedt <rostedt@goodmis.org>,
Peter Zijlstra <peterz@infradead.org>,
Steven Rostedt <rostedt@kernel.org>,
Menglong Dong <menglong8.dong@gmail.com>,
tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com,
kees@kernel.org, samitolvanen@google.com, rppt@kernel.org,
luto@kernel.org, ast@kernel.org, andrii@kernel.org,
linux-kernel@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH] tracing: fgraph: Protect return handler from recursion loop
Date: Mon, 22 Sep 2025 15:38:13 +0200 [thread overview]
Message-ID: <aNFRRa3m6Qm8zzQu@krava> (raw)
In-Reply-To: <20250922151655.1792fa0abc6c3a8d98d052c9@kernel.org>
On Mon, Sep 22, 2025 at 03:16:55PM +0900, Masami Hiramatsu wrote:
> On Sat, 20 Sep 2025 09:45:15 +0200
> Jiri Olsa <olsajiri@gmail.com> wrote:
>
> > On Fri, Sep 19, 2025 at 11:27:46AM -0400, Steven Rostedt wrote:
> > > On Fri, 19 Sep 2025 20:57:36 +0900
> > > "Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
> > >
> > > > From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> > > >
> > > > function_graph_enter_regs() prevents itself from recursion by
> > > > ftrace_test_recursion_trylock(), but __ftrace_return_to_handler(),
> > > > which is called at the exit, does not prevent such recursion.
> > > > Therefore, while it can prevent recursive calls from
> > > > fgraph_ops::entryfunc(), it is not able to prevent recursive calls
> > > > to fgraph from fgraph_ops::retfunc(), resulting in a recursive loop.
> > > > This can lead an unexpected recursion bug reported by Menglong.
> > > >
> > > > is_endbr() is called in __ftrace_return_to_handler -> fprobe_return
> > > > -> kprobe_multi_link_exit_handler -> is_endbr.
> > >
> > > So basically its if the handler for the return part calls something that it
> > > is tracing, it can trigger the recursion?
> > >
> > > >
> > > > To fix this issue, acquire ftrace_test_recursion_trylock() in the
> > > > __ftrace_return_to_handler() after unwind the shadow stack to mark
> > > > this section must prevent recursive call of fgraph inside user-defined
> > > > fgraph_ops::retfunc().
> > > >
> > > > This is essentially a fix to commit 4346ba160409 ("fprobe: Rewrite
> > > > fprobe on function-graph tracer"), because before that fgraph was
> > > > only used from the function graph tracer. Fprobe allowed user to run
> > > > any callbacks from fgraph after that commit.
> > >
> > > I would actually say it's because before this commit, the return handler
> > > callers never called anything that the entry handlers didn't already call.
> > > If there was recursion, the entry handler would catch it (and the entry
> > > tells fgraph if the exit handler should be called).
> > >
> > > The difference here is with fprobes, you can have the exit handler calling
> > > functions that the entry handler does not, which exposes more cases where
> > > recursion could happen.
> >
> > so IIUC we have return kprobe multi probe on is_endbr and now we do:
> >
> > is_endbr()
> > { -> function_graph_enter_regs installs return probe
> > ...
> > } -> __ftrace_return_to_handler
> > fprobe_return
> > kprobe_multi_link_exit_handler
> > is_endbr
> > { -> function_graph_enter_regs installs return probe
> > ...
> > } -> __ftrace_return_to_handler
> > fprobe_return
> > kprobe_multi_link_exit_handler
> > is_endbr
> > { -> function_graph_enter_regs installs return probe
> > ...
> > } -> __ftrace_return_to_handler
> > ... recursion
> >
> >
> > with the fix:
> >
> > is_endbr()
> > { -> function_graph_enter_regs installs return probe
> > ...
> > } -> __ftrace_return_to_handler
> > fprobe_return
> > kprobe_multi_link_exit_handler
> > ...
> > is_endbr
> > { -> function_graph_enter_regs
> > ftrace_test_recursion_trylock fails and we do NOT install return probe
> > ...
> > }
> >
> >
> > there's is_endbr call also in kprobe_multi_link_handler, but it won't
> > trigger recursion, because function_graph_enter_regs already uses
> > ftrace_test_recursion_trylock
> >
> >
> > if above is correct then the fix looks good to me
> >
> > Acked-by: Jiri Olsa <jolsa@kernel.org>
>
> Hi Jiri,
>
> I found ftrace_test_recursion_trylock() allows one nest level, can you
> make sure it is OK?
hum, I recall being surprised by that already in the past,
I thought we fixed that somehow, will check later today
thanks,
jirka
>
> Thank you,
>
> >
> > thanks,
> > jirka
> >
> >
> > >
> > > >
> > > > Reported-by: Menglong Dong <menglong8.dong@gmail.com>
> > > > Closes: https://lore.kernel.org/all/20250918120939.1706585-1-dongml2@chinatelecom.cn/
> > > > Fixes: 4346ba160409 ("fprobe: Rewrite fprobe on function-graph tracer")
> > > > Cc: stable@vger.kernel.org
> > > > Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> > > > ---
> > > > kernel/trace/fgraph.c | 12 ++++++++++++
> > > > 1 file changed, 12 insertions(+)
> > > >
> > > > diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
> > > > index 1e3b32b1e82c..08dde420635b 100644
> > > > --- a/kernel/trace/fgraph.c
> > > > +++ b/kernel/trace/fgraph.c
> > > > @@ -815,6 +815,7 @@ __ftrace_return_to_handler(struct ftrace_regs *fregs, unsigned long frame_pointe
> > > > unsigned long bitmap;
> > > > unsigned long ret;
> > > > int offset;
> > > > + int bit;
> > > > int i;
> > > >
> > > > ret_stack = ftrace_pop_return_trace(&trace, &ret, frame_pointer, &offset);
> > > > @@ -829,6 +830,15 @@ __ftrace_return_to_handler(struct ftrace_regs *fregs, unsigned long frame_pointe
> > > > if (fregs)
> > > > ftrace_regs_set_instruction_pointer(fregs, ret);
> > > >
> > > > + bit = ftrace_test_recursion_trylock(trace.func, ret);
> > > > + /*
> > > > + * This must be succeeded because the entry handler returns before
> > > > + * modifying the return address if it is nested. Anyway, we need to
> > > > + * avoid calling user callbacks if it is nested.
> > > > + */
> > > > + if (WARN_ON_ONCE(bit < 0))
> > >
> > > I'm not so sure we need the warn on here. We should probably hook it to the
> > > recursion detection infrastructure that the function tracer has.
> > >
> > > The reason I would say not to have the warn on, is because we don't have a
> > > warn on for recursion happening at the entry handler. Because this now is
> > > exposed by fprobe allowing different routines to be called at exit than
> > > what is used in entry, it can easily be triggered.
> > >
> > > -- Steve
> > >
> > >
> > >
> > > > + goto out;
> > > > +
> > > > #ifdef CONFIG_FUNCTION_GRAPH_RETVAL
> > > > trace.retval = ftrace_regs_get_return_value(fregs);
> > > > #endif
> > > > @@ -852,6 +862,8 @@ __ftrace_return_to_handler(struct ftrace_regs *fregs, unsigned long frame_pointe
> > > > }
> > > > }
> > > >
> > > > + ftrace_test_recursion_unlock(bit);
> > > > +out:
> > > > /*
> > > > * The ftrace_graph_return() may still access the current
> > > > * ret_stack structure, we need to make sure the update of
> > >
>
>
> --
> Masami Hiramatsu (Google) <mhiramat@kernel.org>
next prev parent reply other threads:[~2025-09-22 13:38 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-18 12:09 [PATCH] x86/ibt: make is_endbr() notrace Menglong Dong
2025-09-18 13:05 ` Peter Zijlstra
2025-09-18 13:32 ` Menglong Dong
2025-09-18 16:02 ` Alexei Starovoitov
2025-09-18 16:59 ` Peter Zijlstra
2025-09-18 17:53 ` Alexei Starovoitov
2025-09-19 1:13 ` Menglong Dong
2025-09-22 6:52 ` Peter Zijlstra
2025-09-22 7:13 ` menglong.dong
2025-09-22 7:19 ` Peter Zijlstra
2025-09-22 7:21 ` Menglong Dong
2025-09-22 6:36 ` Peter Zijlstra
2025-09-18 16:56 ` Peter Zijlstra
2025-09-19 12:35 ` Masami Hiramatsu
2025-09-19 8:52 ` Masami Hiramatsu
2025-09-19 8:58 ` Menglong Dong
2025-09-19 12:32 ` Masami Hiramatsu
2025-09-19 11:57 ` [PATCH] tracing: fgraph: Protect return handler from recursion loop Masami Hiramatsu (Google)
2025-09-19 15:27 ` Steven Rostedt
2025-09-20 7:45 ` Jiri Olsa
2025-09-22 6:16 ` Masami Hiramatsu
2025-09-22 13:38 ` Jiri Olsa [this message]
2025-09-22 14:42 ` Steven Rostedt
2025-09-22 19:45 ` Jiri Olsa
2025-09-21 4:05 ` Masami Hiramatsu
2025-09-21 22:52 ` Steven Rostedt
2025-09-24 22:58 ` Masami Hiramatsu
2025-09-20 13:39 ` Menglong Dong
2025-09-21 4:06 ` Masami Hiramatsu
2025-09-21 23:00 ` Steven Rostedt
2025-09-24 22:59 ` Masami Hiramatsu
2025-09-22 5:19 ` Masami Hiramatsu
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=aNFRRa3m6Qm8zzQu@krava \
--to=olsajiri@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bp@alien8.de \
--cc=bpf@vger.kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=menglong8.dong@gmail.com \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=rostedt@kernel.org \
--cc=rppt@kernel.org \
--cc=samitolvanen@google.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.