]> git.hungrycats.org Git - linux/commitdiff
bpf, perf: delay release of BPF prog after grace period
authorDaniel Borkmann <daniel@iogearbox.net>
Mon, 27 Jun 2016 19:38:11 +0000 (21:38 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Jul 2016 16:30:01 +0000 (09:30 -0700)
[ Upstream commit ceb56070359b7329b5678b5d95a376fcb24767be ]

Commit dead9f29ddcc ("perf: Fix race in BPF program unregister") moved
destruction of BPF program from free_event_rcu() callback to __free_event(),
which is problematic if used with tail calls: if prog A is attached as
trace event directly, but at the same time present in a tail call map used
by another trace event program elsewhere, then we need to delay destruction
via RCU grace period since it can still be in use by the program doing the
tail call (the prog first needs to be dropped from the tail call map, then
trace event with prog A attached destroyed, so we get immediate destruction).

Fixes: dead9f29ddcc ("perf: Fix race in BPF program unregister")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Jann Horn <jann@thejh.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/linux/bpf.h
kernel/events/core.c

index f1d5c5acc8dd58cd92df76915391b4737d90c083..ca80d5830bfd775c0fa1a45ed6347a96f88b7376 100644 (file)
@@ -229,6 +229,10 @@ static inline struct bpf_prog *bpf_prog_get(u32 ufd)
 static inline void bpf_prog_put(struct bpf_prog *prog)
 {
 }
+
+static inline void bpf_prog_put_rcu(struct bpf_prog *prog)
+{
+}
 #endif /* CONFIG_BPF_SYSCALL */
 
 /* verifier prototypes for helper functions called from eBPF programs */
index c0ded24166158f26b0c4f3ce1c47dd065e28700c..a69c90cea05d0e098ebff4fcfc53906ab499eb35 100644 (file)
@@ -7143,7 +7143,7 @@ static void perf_event_free_bpf_prog(struct perf_event *event)
        prog = event->tp_event->prog;
        if (prog) {
                event->tp_event->prog = NULL;
-               bpf_prog_put(prog);
+               bpf_prog_put_rcu(prog);
        }
 }