Skip to content

Commit 1a4f1ec

Browse files
yonghong-songgregkh
authored andcommitted
bpf: one perf event close won't free bpf program attached by another perf event
[ Upstream commit ec9dd352d591f0c90402ec67a317c1ed4fb2e638 ] This patch fixes a bug exhibited by the following scenario: 1. fd1 = perf_event_open with attr.config = ID1 2. attach bpf program prog1 to fd1 3. fd2 = perf_event_open with attr.config = ID1 <this will be successful> 4. user program closes fd2 and prog1 is detached from the tracepoint. 5. user program with fd1 does not work properly as tracepoint no output any more. The issue happens at step 4. Multiple perf_event_open can be called successfully, but only one bpf prog pointer in the tp_event. In the current logic, any fd release for the same tp_event will free the tp_event->prog. The fix is to free tp_event->prog only when the closing fd corresponds to the one which registered the program. Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5be6824 commit 1a4f1ec

2 files changed

Lines changed: 3 additions & 1 deletion

File tree

include/linux/trace_events.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ struct trace_event_call {
301301
int perf_refcount;
302302
struct hlist_head __percpu *perf_events;
303303
struct bpf_prog *prog;
304+
struct perf_event *bpf_prog_owner;
304305

305306
int (*perf_perm)(struct trace_event_call *,
306307
struct perf_event *);

kernel/events/core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7108,6 +7108,7 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)
71087108
}
71097109

71107110
event->tp_event->prog = prog;
7111+
event->tp_event->bpf_prog_owner = event;
71117112

71127113
return 0;
71137114
}
@@ -7120,7 +7121,7 @@ static void perf_event_free_bpf_prog(struct perf_event *event)
71207121
return;
71217122

71227123
prog = event->tp_event->prog;
7123-
if (prog) {
7124+
if (prog && event->tp_event->bpf_prog_owner == event) {
71247125
event->tp_event->prog = NULL;
71257126
bpf_prog_put_rcu(prog);
71267127
}

0 commit comments

Comments
 (0)