diff options
author | Stanislav Fomichev <sdf@google.com> | 2019-05-28 17:14:44 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-05-29 09:17:35 -0400 |
commit | e672db03ab0e43e41ab6f8b2156a10d6e40f243d (patch) | |
tree | 0d508e5f0d220b177707211d90a206265a5aa9cb | |
parent | dbcc1ba26e43bd32cb308e50ac4cb4a29d2f5967 (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.c | 18 |
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 |
23 | struct bpf_trace_module { | 26 | struct bpf_trace_module { |
24 | struct module *module; | 27 | struct module *module; |
@@ -1099,7 +1102,7 @@ static DEFINE_MUTEX(bpf_event_mutex); | |||
1099 | int perf_event_attach_bpf_prog(struct perf_event *event, | 1102 | int 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 | ||
1141 | void perf_event_detach_bpf_prog(struct perf_event *event) | 1144 | void 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)) || |