mirror of
https://github.com/torvalds/linux.git
synced 2026-10-07 22:37:45 -04:00
perf: Fix race in BPF program unregister
there is a race between perf_event_free_bpf_prog() and free_trace_kprobe():
__free_event()
event->destroy(event)
tp_perf_event_destroy()
perf_trace_destroy()
perf_trace_event_unreg()
which is dropping event->tp_event->perf_refcount and allows to proceed in:
unregister_trace_kprobe()
unregister_kprobe_event()
trace_remove_event_call()
probe_remove_event_call()
free_trace_kprobe()
while __free_event does:
call_rcu(&event->rcu_head, free_event_rcu);
free_event_rcu()
perf_event_free_bpf_prog()
To fix the race simply move perf_event_free_bpf_prog() before
event->destroy(), since event->tp_event is still valid at that point.
Note, perf_trace_destroy() is not racing with trace_remove_event_call()
since they both grab event_mutex.
Reported-by: Wang Nan <[email protected]>
Signed-off-by: Alexei Starovoitov <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Fixes: 2541517c32 ("tracing, perf: Implement BPF programs attached to kprobes")
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
1 parent
ba155e2d21
commit
dead9f29dd
1 file changed
+2
-1
@@ -3442,7 +3442,6 @@ static void free_event_rcu(struct rcu_head *head)
|
||||
if (event->ns)
|
||||
put_pid_ns(event->ns);
|
||||
perf_event_free_filter(event);
|
||||
perf_event_free_bpf_prog(event);
|
||||
kfree(event);
|
||||
}
|
||||
|
||||
@@ -3573,6 +3572,8 @@ static void __free_event(struct perf_event *event)
|
||||
put_callchain_buffers();
|
||||
}
|
||||
|
||||
perf_event_free_bpf_prog(event);
|
||||
|
||||
if (event->destroy)
|
||||
event->destroy(event);
|
||||
|
||||
|
||||
Reference in new issue
Block a user