* [PATCH v2] fprobe: Fix unregister_fprobe() to wait for RCU grace period
@ 2026-05-07 7:46 Masami Hiramatsu (Google)
2026-05-14 17:12 ` patchwork-bot+netdevbpf
0 siblings, 1 reply; 2+ messages in thread
From: Masami Hiramatsu (Google) @ 2026-05-07 7:46 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Jiri Olsa
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel, bpf
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Commit 4346ba1604093 ("fprobe: Rewrite fprobe on function-graph tracer")
changed fprobe to register struct fprobe to an rcu-hlist, but it forgot
to wait for RCU GP. Thus there can be use-after-free if the fprobe is
released right after unregistering. This can be happened on fprobe
event and sample module code.
To fix this issue, add synchronize_rcu() in unregister_fprobe().
Note that BPF is OK because fprobe is used as a part of
bpf_kprobe_multi_link. This unregisters its fprobe in
bpf_kprobe_multi_link_release() and it is deallocated via
bpf_kprobe_multi_link_dealloc(), which is invoked from
bpf_link_defer_dealloc_rcu_gp() RCU callback.
For BPF, this also introduced unregister_fprobe_async() which does
NOT wait for RCU grace priod.
Fixes: 4346ba1604093 ("fprobe: Rewrite fprobe on function-graph tracer")
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
Changes from v1 [1]:
- Rewrite with async API.
- Apply async API only to BPF.
[1] https://lore.kernel.org/all/177729179863.401400.6063130067239479972.stgit@mhiramat.tok.corp.google.com/
---
include/linux/fprobe.h | 5 +++++
kernel/trace/bpf_trace.c | 3 ++-
kernel/trace/fprobe.c | 23 +++++++++++++++++++++--
3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h
index 0a3bcd1718f3..be1b38c981d4 100644
--- a/include/linux/fprobe.h
+++ b/include/linux/fprobe.h
@@ -94,6 +94,7 @@ int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter
int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num);
int register_fprobe_syms(struct fprobe *fp, const char **syms, int num);
int unregister_fprobe(struct fprobe *fp);
+int unregister_fprobe_async(struct fprobe *fp);
bool fprobe_is_registered(struct fprobe *fp);
int fprobe_count_ips_from_filter(const char *filter, const char *notfilter);
#else
@@ -113,6 +114,10 @@ static inline int unregister_fprobe(struct fprobe *fp)
{
return -EOPNOTSUPP;
}
+static inline int unregister_fprobe_async(struct fprobe *fp)
+{
+ return -EOPNOTSUPP;
+}
static inline bool fprobe_is_registered(struct fprobe *fp)
{
return false;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index af7079aa0f36..a02bd258677e 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -2384,7 +2384,8 @@ static void bpf_kprobe_multi_link_release(struct bpf_link *link)
struct bpf_kprobe_multi_link *kmulti_link;
kmulti_link = container_of(link, struct bpf_kprobe_multi_link, link);
- unregister_fprobe(&kmulti_link->fp);
+ /* Don't wait for RCU GP here. */
+ unregister_fprobe_async(&kmulti_link->fp);
kprobe_multi_put_modules(kmulti_link->mods, kmulti_link->mods_cnt);
}
diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
index cc49ebd2a773..f378613ad120 100644
--- a/kernel/trace/fprobe.c
+++ b/kernel/trace/fprobe.c
@@ -1093,14 +1093,15 @@ static int unregister_fprobe_nolock(struct fprobe *fp)
}
/**
- * unregister_fprobe() - Unregister fprobe.
+ * unregister_fprobe_async() - Unregister fprobe without RCU GP wait
* @fp: A fprobe data structure to be unregistered.
*
* Unregister fprobe (and remove ftrace hooks from the function entries).
+ * This function will NOT wait until the fprobe is no longer used.
*
* Return 0 if @fp is unregistered successfully, -errno if not.
*/
-int unregister_fprobe(struct fprobe *fp)
+int unregister_fprobe_async(struct fprobe *fp)
{
guard(mutex)(&fprobe_mutex);
if (!fp || !fprobe_registered(fp))
@@ -1108,6 +1109,24 @@ int unregister_fprobe(struct fprobe *fp)
return unregister_fprobe_nolock(fp);
}
+
+/**
+ * unregister_fprobe() - Unregister fprobe with RCU GP wait
+ * @fp: A fprobe data structure to be unregistered.
+ *
+ * Unregister fprobe (and remove ftrace hooks from the function entries).
+ * This function will block until the fprobe is no longer used.
+ *
+ * Return 0 if @fp is unregistered successfully, -errno if not.
+ */
+int unregister_fprobe(struct fprobe *fp)
+{
+ int ret = unregister_fprobe_async(fp);
+
+ if (!ret)
+ synchronize_rcu();
+ return ret;
+}
EXPORT_SYMBOL_GPL(unregister_fprobe);
static int __init fprobe_initcall(void)
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v2] fprobe: Fix unregister_fprobe() to wait for RCU grace period
2026-05-07 7:46 [PATCH v2] fprobe: Fix unregister_fprobe() to wait for RCU grace period Masami Hiramatsu (Google)
@ 2026-05-14 17:12 ` patchwork-bot+netdevbpf
0 siblings, 0 replies; 2+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-05-14 17:12 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: rostedt, ast, daniel, andrii, jolsa, mathieu.desnoyers,
linux-kernel, linux-trace-kernel, bpf
Hello:
This patch was applied to netdev/net.git (main)
by Masami Hiramatsu (Google) <mhiramat@kernel.org>:
On Thu, 7 May 2026 16:46:29 +0900 you wrote:
> From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
> Commit 4346ba1604093 ("fprobe: Rewrite fprobe on function-graph tracer")
> changed fprobe to register struct fprobe to an rcu-hlist, but it forgot
> to wait for RCU GP. Thus there can be use-after-free if the fprobe is
> released right after unregistering. This can be happened on fprobe
> event and sample module code.
>
> [...]
Here is the summary with links:
- [v2] fprobe: Fix unregister_fprobe() to wait for RCU grace period
https://git.kernel.org/netdev/net/c/657b594b2084
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-05-14 17:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-07 7:46 [PATCH v2] fprobe: Fix unregister_fprobe() to wait for RCU grace period Masami Hiramatsu (Google)
2026-05-14 17:12 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox