[PATCH 4.6 22/81] bpf, trace: use READ_ONCE for retrieving file ptr

Greg Kroah-Hartman
2016-06-22T22:47:01Z

From: Daniel Borkmann <daniel@iogearbox.net>

[ Upstream commit 5b6c1b4d46b0dae4edea636a776d09f2064f4cd7 ]

In bpf_perf_event_read() and bpf_perf_event_output(), we must use
READ_ONCE() for fetching the struct file pointer, which could get
updated concurrently, so we must prevent the compiler from potential
refetching.

We already do this with tail calls for fetching the related bpf_prog,
but not so on stored perf events. Semantics for both are the same
with regards to updates.

Fixes: a43eec304259 ("bpf: introduce bpf_perf_event_output() helper")
Fixes: 35578d798400 ("bpf: Implement function bpf_perf_event_read() that get the selected hardware PMU conuter")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/bpf_trace.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -194,7 +194,7 @@ static u64 bpf_perf_event_read(u64 r1, u
if (unlikely(index >= array->map.max_entries))
return -E2BIG;

- file = (struct file *)array->ptrs[index];
+ file = READ_ONCE(array->ptrs[index]);
if (unlikely(!file))
return -ENOENT;

@@ -238,7 +238,7 @@ static u64 bpf_perf_event_output(u64 r1,
if (unlikely(index >= array->map.max_entries))
return -E2BIG;

- file = (struct file *)array->ptrs[index];
+ file = READ_ONCE(array->ptrs[index]);
if (unlikely(!file))
return -ENOENT;