summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2017-09-18 16:38:36 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-21 17:09:02 +0200
commit1a4f1ecdb2573cebc9ef1b8bbed0185c0bd45e6c (patch)
tree83ab4e777421a812f34038e2ad0263149caf9cc7 /include
parent5be6824b9704f926c26c844b373aacdc7e827ab6 (diff)
downloadlinux-stable-1a4f1ecdb2573cebc9ef1b8bbed0185c0bd45e6c.tar.gz
linux-stable-1a4f1ecdb2573cebc9ef1b8bbed0185c0bd45e6c.tar.bz2
linux-stable-1a4f1ecdb2573cebc9ef1b8bbed0185c0bd45e6c.zip
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>
Diffstat (limited to 'include')
-rw-r--r--include/linux/trace_events.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 925730bc9fc1..311176f290b2 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -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 *);