aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Fomichev <sdf@google.com>2019-05-28 17:14:44 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2019-05-29 09:17:35 -0400
commite672db03ab0e43e41ab6f8b2156a10d6e40f243d (patch)
tree0d508e5f0d220b177707211d90a206265a5aa9cb
parentdbcc1ba26e43bd32cb308e50ac4cb4a29d2f5967 (diff)
bpf: tracing: properly use bpf_prog_array api
Now that we don't have __rcu markers on the bpf_prog_array helpers, let's use proper rcu_dereference_protected to obtain array pointer under mutex. Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Ingo Molnar <mingo@redhat.com> Signed-off-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--kernel/trace/bpf_trace.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index fe73926a07cd..3994a231eb92 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -19,6 +19,9 @@
19#include "trace_probe.h" 19#include "trace_probe.h"
20#include "trace.h" 20#include "trace.h"
21 21
22#define bpf_event_rcu_dereference(p) \
23 rcu_dereference_protected(p, lockdep_is_held(&bpf_event_mutex))
24
22#ifdef CONFIG_MODULES 25#ifdef CONFIG_MODULES
23struct bpf_trace_module { 26struct bpf_trace_module {
24 struct module *module; 27 struct module *module;
@@ -1099,7 +1102,7 @@ static DEFINE_MUTEX(bpf_event_mutex);
1099int perf_event_attach_bpf_prog(struct perf_event *event, 1102int perf_event_attach_bpf_prog(struct perf_event *event,
1100 struct bpf_prog *prog) 1103 struct bpf_prog *prog)
1101{ 1104{
1102 struct bpf_prog_array __rcu *old_array; 1105 struct bpf_prog_array *old_array;
1103 struct bpf_prog_array *new_array; 1106 struct bpf_prog_array *new_array;
1104 int ret = -EEXIST; 1107 int ret = -EEXIST;
1105 1108
@@ -1117,7 +1120,7 @@ int perf_event_attach_bpf_prog(struct perf_event *event,
1117 if (event->prog) 1120 if (event->prog)
1118 goto unlock; 1121 goto unlock;
1119 1122
1120 old_array = event->tp_event->prog_array; 1123 old_array = bpf_event_rcu_dereference(event->tp_event->prog_array);
1121 if (old_array && 1124 if (old_array &&
1122 bpf_prog_array_length(old_array) >= BPF_TRACE_MAX_PROGS) { 1125 bpf_prog_array_length(old_array) >= BPF_TRACE_MAX_PROGS) {
1123 ret = -E2BIG; 1126 ret = -E2BIG;
@@ -1140,7 +1143,7 @@ unlock:
1140 1143
1141void perf_event_detach_bpf_prog(struct perf_event *event) 1144void perf_event_detach_bpf_prog(struct perf_event *event)
1142{ 1145{
1143 struct bpf_prog_array __rcu *old_array; 1146 struct bpf_prog_array *old_array;
1144 struct bpf_prog_array *new_array; 1147 struct bpf_prog_array *new_array;
1145 int ret; 1148 int ret;
1146 1149
@@ -1149,7 +1152,7 @@ void perf_event_detach_bpf_prog(struct perf_event *event)
1149 if (!event->prog) 1152 if (!event->prog)
1150 goto unlock; 1153 goto unlock;
1151 1154
1152 old_array = event->tp_event->prog_array; 1155 old_array = bpf_event_rcu_dereference(event->tp_event->prog_array);
1153 ret = bpf_prog_array_copy(old_array, event->prog, NULL, &new_array); 1156 ret = bpf_prog_array_copy(old_array, event->prog, NULL, &new_array);
1154 if (ret == -ENOENT) 1157 if (ret == -ENOENT)
1155 goto unlock; 1158 goto unlock;
@@ -1171,6 +1174,7 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)
1171{ 1174{
1172 struct perf_event_query_bpf __user *uquery = info; 1175 struct perf_event_query_bpf __user *uquery = info;
1173 struct perf_event_query_bpf query = {}; 1176 struct perf_event_query_bpf query = {};
1177 struct bpf_prog_array *progs;
1174 u32 *ids, prog_cnt, ids_len; 1178 u32 *ids, prog_cnt, ids_len;
1175 int ret; 1179 int ret;
1176 1180
@@ -1195,10 +1199,8 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)
1195 */ 1199 */
1196 1200
1197 mutex_lock(&bpf_event_mutex); 1201 mutex_lock(&bpf_event_mutex);
1198 ret = bpf_prog_array_copy_info(event->tp_event->prog_array, 1202 progs = bpf_event_rcu_dereference(event->tp_event->prog_array);
1199 ids, 1203 ret = bpf_prog_array_copy_info(progs, ids, ids_len, &prog_cnt);
1200 ids_len,
1201 &prog_cnt);
1202 mutex_unlock(&bpf_event_mutex); 1204 mutex_unlock(&bpf_event_mutex);
1203 1205
1204 if (copy_to_user(&uquery->prog_cnt, &prog_cnt, sizeof(prog_cnt)) || 1206 if (copy_to_user(&uquery->prog_cnt, &prog_cnt, sizeof(prog_cnt)) ||