Skip to contentSkip to conversation

Patch "bpf: one perf event close won't free bpf program attached by another perf event" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Oct 19, 2017

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

bpf: one perf event close won't free bpf program attached by another perf event

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
bpf-one-perf-event-close-won-t-free-bpf-program-attached-by-another-perf-event.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Thu Oct 19 14:05:19 CEST 2017

From: Yonghong Song <[email protected]>
Date: Mon, 18 Sep 2017 16:38:36 -0700
Subject: bpf: one perf event close won't free bpf program attached by another perf event

From: Yonghong Song <[email protected]>

[ 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.

---
 include/linux/trace_events.h |    1 +
 kernel/events/core.c         |    3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)
include/linux/trace_events.h +1 -0
@@ -301,6 +301,7 @@ struct trace_event_call {
 	int				perf_refcount;
 	struct hlist_head __percpu	*perf_events;
 	struct bpf_prog			*prog;
+	struct perf_event		*bpf_prog_owner;
 
 	int	(*perf_perm)(struct trace_event_call *,
 			     struct perf_event *);
kernel/events/core.c +2 -1
@@ -7108,6 +7108,7 @@ static int perf_event_set_bpf_prog(struc
 	}
 
 	event->tp_event->prog = prog;
+	event->tp_event->bpf_prog_owner = event;
 
 	return 0;
 }
@@ -7120,7 +7121,7 @@ static void perf_event_free_bpf_prog(str
 		return;
 
 	prog = event->tp_event->prog;
-	if (prog) {
+	if (prog && event->tp_event->bpf_prog_owner == event) {
 		event->tp_event->prog = NULL;
 		bpf_prog_put_rcu(prog);
 	}

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/bpf-one-perf-event-close-won-t-free-bpf-program-attached-by-another-perf-event.patch