summaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_probe.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2021-08-19 19:26:02 +0900
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2021-08-19 09:15:19 -0400
commit8e242060c6a4947e8ae7d29794af6a581db08841 (patch)
tree83539c379970633a6fbc3b98a472a7edf0449ef0 /kernel/trace/trace_probe.c
parent8565a45d0858078b63c7d84074a21a42ba9ebf01 (diff)
downloadlinux-8e242060c6a4947e8ae7d29794af6a581db08841.tar.gz
linux-8e242060c6a4947e8ae7d29794af6a581db08841.tar.bz2
linux-8e242060c6a4947e8ae7d29794af6a581db08841.zip
tracing/probes: Reject events which have the same name of existing one
Since kprobe_events and uprobe_events only check whether the other same-type probe event has the same name or not, if the user gives the same name of the existing tracepoint event (or the other type of probe events), it silently fails to create the tracefs entry (but registered.) as below. /sys/kernel/tracing # ls events/task/task_rename enable filter format hist id trigger /sys/kernel/tracing # echo p:task/task_rename vfs_read >> kprobe_events [ 113.048508] Could not create tracefs 'task_rename' directory /sys/kernel/tracing # cat kprobe_events p:task/task_rename vfs_read To fix this issue, check whether the existing events have the same name or not in trace_probe_register_event_call(). If exists, it rejects to register the new event. Link: https://lkml.kernel.org/r/162936876189.187130.17558311387542061930.stgit@devnote2 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_probe.c')
-rw-r--r--kernel/trace/trace_probe.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 9c9c83a063b2..782c00eb6859 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -1047,11 +1047,36 @@ error:
return ret;
}
+static struct trace_event_call *
+find_trace_event_call(const char *system, const char *event_name)
+{
+ struct trace_event_call *tp_event;
+ const char *name;
+
+ list_for_each_entry(tp_event, &ftrace_events, list) {
+ if (!tp_event->class->system ||
+ strcmp(system, tp_event->class->system))
+ continue;
+ name = trace_event_name(tp_event);
+ if (!name || strcmp(event_name, name))
+ continue;
+ return tp_event;
+ }
+
+ return NULL;
+}
+
int trace_probe_register_event_call(struct trace_probe *tp)
{
struct trace_event_call *call = trace_probe_event_call(tp);
int ret;
+ lockdep_assert_held(&event_mutex);
+
+ if (find_trace_event_call(trace_probe_group_name(tp),
+ trace_probe_name(tp)))
+ return -EEXIST;
+
ret = register_trace_event(&call->event);
if (!ret)
return -ENODEV;