Skip to content

Commit

Permalink
tracing/probes: Reject events which have the same name of existing one
Browse files Browse the repository at this point in the history
[ Upstream commit 8e24206 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
mhiramat authored and gregkh committed Sep 22, 2021
1 parent 86ddc73 commit 53347ed
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 2 deletions.
6 changes: 5 additions & 1 deletion kernel/trace/trace_kprobe.c
Expand Up @@ -647,7 +647,11 @@ static int register_trace_kprobe(struct trace_kprobe *tk)
/* Register new event */
ret = register_kprobe_event(tk);
if (ret) {
pr_warn("Failed to register probe event(%d)\n", ret);
if (ret == -EEXIST) {
trace_probe_log_set_index(0);
trace_probe_log_err(0, EVENT_EXIST);
} else
pr_warn("Failed to register probe event(%d)\n", ret);
goto end;
}

Expand Down
25 changes: 25 additions & 0 deletions kernel/trace/trace_probe.c
Expand Up @@ -1029,11 +1029,36 @@ int trace_probe_init(struct trace_probe *tp, const char *event,
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;
Expand Down
1 change: 1 addition & 0 deletions kernel/trace/trace_probe.h
Expand Up @@ -399,6 +399,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
C(NO_EVENT_NAME, "Event name is not specified"), \
C(EVENT_TOO_LONG, "Event name is too long"), \
C(BAD_EVENT_NAME, "Event name must follow the same rules as C identifiers"), \
C(EVENT_EXIST, "Given group/event name is already used by another event"), \
C(RETVAL_ON_PROBE, "$retval is not available on probe"), \
C(BAD_STACK_NUM, "Invalid stack number"), \
C(BAD_ARG_NUM, "Invalid argument number"), \
Expand Down
6 changes: 5 additions & 1 deletion kernel/trace/trace_uprobe.c
Expand Up @@ -514,7 +514,11 @@ static int register_trace_uprobe(struct trace_uprobe *tu)

ret = register_uprobe_event(tu);
if (ret) {
pr_warn("Failed to register probe event(%d)\n", ret);
if (ret == -EEXIST) {
trace_probe_log_set_index(0);
trace_probe_log_err(0, EVENT_EXIST);
} else
pr_warn("Failed to register probe event(%d)\n", ret);
goto end;
}

Expand Down

0 comments on commit 53347ed

Please sign in to comment.