Skip to content

Commit

Permalink
tracing/eprobes: Have event probes be consistent with kprobes and upr…
Browse files Browse the repository at this point in the history
…obes

Currently, if a symbol "@" is attempted to be used with an event probe
(eprobes), it will cause a NULL pointer dereference crash.

Both kprobes and uprobes can reference data other than the main registers.
Such as immediate address, symbols and the current task name. Have eprobes
do the same thing.

For "comm", if "comm" is used and the event being attached to does not
have the "comm" field, then make it the "$comm" that kprobes has. This is
consistent to the way histograms and filters work.

Link: https://lkml.kernel.org/r/[email protected]

Cc: [email protected]
Cc: Ingo Molnar <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Tzvetomir Stoyanov <[email protected]>
Cc: Tom Zanussi <[email protected]>
Fixes: 7491e2c ("tracing: Add a probe that attaches to trace events")
Signed-off-by: Steven Rostedt (Google) <[email protected]>
  • Loading branch information
rostedt committed Aug 21, 2022
1 parent f04dec9 commit 6a832ec
Showing 1 changed file with 64 additions and 6 deletions.
70 changes: 64 additions & 6 deletions kernel/trace/trace_eprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ static int trace_eprobe_tp_arg_update(struct trace_eprobe *ep, int i)
struct probe_arg *parg = &ep->tp.args[i];
struct ftrace_event_field *field;
struct list_head *head;
int ret = -ENOENT;

head = trace_get_fields(ep->event);
list_for_each_entry(field, head, link) {
Expand All @@ -236,9 +237,20 @@ static int trace_eprobe_tp_arg_update(struct trace_eprobe *ep, int i)
return 0;
}
}

/*
* Argument not found on event. But allow for comm and COMM
* to be used to get the current->comm.
*/
if (strcmp(parg->code->data, "COMM") == 0 ||
strcmp(parg->code->data, "comm") == 0) {
parg->code->op = FETCH_OP_COMM;
ret = 0;
}

kfree(parg->code->data);
parg->code->data = NULL;
return -ENOENT;
return ret;
}

static int eprobe_event_define_fields(struct trace_event_call *event_call)
Expand Down Expand Up @@ -363,16 +375,38 @@ static unsigned long get_event_field(struct fetch_insn *code, void *rec)

static int get_eprobe_size(struct trace_probe *tp, void *rec)
{
struct fetch_insn *code;
struct probe_arg *arg;
int i, len, ret = 0;

for (i = 0; i < tp->nr_args; i++) {
arg = tp->args + i;
if (unlikely(arg->dynamic)) {
if (arg->dynamic) {
unsigned long val;

val = get_event_field(arg->code, rec);
len = process_fetch_insn_bottom(arg->code + 1, val, NULL, NULL);
code = arg->code;
retry:
switch (code->op) {
case FETCH_OP_TP_ARG:
val = get_event_field(code, rec);
break;
case FETCH_OP_IMM:
val = code->immediate;
break;
case FETCH_OP_COMM:
val = (unsigned long)current->comm;
break;
case FETCH_OP_DATA:
val = (unsigned long)code->data;
break;
case FETCH_NOP_SYMBOL: /* Ignore a place holder */
code++;
goto retry;
default:
continue;
}
code++;
len = process_fetch_insn_bottom(code, val, NULL, NULL);
if (len > 0)
ret += len;
}
Expand All @@ -390,8 +424,28 @@ process_fetch_insn(struct fetch_insn *code, void *rec, void *dest,
{
unsigned long val;

val = get_event_field(code, rec);
return process_fetch_insn_bottom(code + 1, val, dest, base);
retry:
switch (code->op) {
case FETCH_OP_TP_ARG:
val = get_event_field(code, rec);
break;
case FETCH_OP_IMM:
val = code->immediate;
break;
case FETCH_OP_COMM:
val = (unsigned long)current->comm;
break;
case FETCH_OP_DATA:
val = (unsigned long)code->data;
break;
case FETCH_NOP_SYMBOL: /* Ignore a place holder */
code++;
goto retry;
default:
return -EILSEQ;
}
code++;
return process_fetch_insn_bottom(code, val, dest, base);
}
NOKPROBE_SYMBOL(process_fetch_insn)

Expand Down Expand Up @@ -866,6 +920,10 @@ static int trace_eprobe_tp_update_arg(struct trace_eprobe *ep, const char *argv[
trace_probe_log_err(0, BAD_ATTACH_ARG);
}

/* Handle symbols "@" */
if (!ret)
ret = traceprobe_update_arg(&ep->tp.args[i]);

return ret;
}

Expand Down

0 comments on commit 6a832ec

Please sign in to comment.