diff options
author | Masami Hiramatsu <mhiramat@kernel.org> | 2018-03-17 08:38:10 -0400 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2018-03-23 12:02:37 -0400 |
commit | c5d343b6b7badd1f5fe0873eff2e8d63a193e732 (patch) | |
tree | 56f571ff28c377ee42c9f3fb30f150e451c158a6 | |
parent | 661e50bc853209e41a5c14a290ca4decc43cbfd1 (diff) |
tracing: probeevent: Fix to support minus offset from symbol
In Documentation/trace/kprobetrace.txt, it says
@SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)
However, the parser doesn't parse minus offset correctly, since
commit 2fba0c8867af ("tracing/kprobes: Fix probe offset to be
unsigned") drops minus ("-") offset support for kprobe probe
address usage.
This fixes the traceprobe_split_symbol_offset() to parse minus
offset again with checking the offset range, and add a minus
offset check in kprobe probe address usage.
Link: http://lkml.kernel.org/r/152129028983.31874.13419301530285775521.stgit@devbox
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Tom Zanussi <tom.zanussi@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: stable@vger.kernel.org
Fixes: 2fba0c8867af ("tracing/kprobes: Fix probe offset to be unsigned")
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-rw-r--r-- | kernel/trace/trace_kprobe.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace_probe.c | 8 | ||||
-rw-r--r-- | kernel/trace/trace_probe.h | 2 |
3 files changed, 6 insertions, 8 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1fad24acd444..ae4147eaebd4 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -659,7 +659,7 @@ static int create_trace_kprobe(int argc, char **argv) | |||
659 | char *symbol = NULL, *event = NULL, *group = NULL; | 659 | char *symbol = NULL, *event = NULL, *group = NULL; |
660 | int maxactive = 0; | 660 | int maxactive = 0; |
661 | char *arg; | 661 | char *arg; |
662 | unsigned long offset = 0; | 662 | long offset = 0; |
663 | void *addr = NULL; | 663 | void *addr = NULL; |
664 | char buf[MAX_EVENT_NAME_LEN]; | 664 | char buf[MAX_EVENT_NAME_LEN]; |
665 | 665 | ||
@@ -747,7 +747,7 @@ static int create_trace_kprobe(int argc, char **argv) | |||
747 | symbol = argv[1]; | 747 | symbol = argv[1]; |
748 | /* TODO: support .init module functions */ | 748 | /* TODO: support .init module functions */ |
749 | ret = traceprobe_split_symbol_offset(symbol, &offset); | 749 | ret = traceprobe_split_symbol_offset(symbol, &offset); |
750 | if (ret) { | 750 | if (ret || offset < 0 || offset > UINT_MAX) { |
751 | pr_info("Failed to parse either an address or a symbol.\n"); | 751 | pr_info("Failed to parse either an address or a symbol.\n"); |
752 | return ret; | 752 | return ret; |
753 | } | 753 | } |
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index d59357308677..daf54bda4dc8 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c | |||
@@ -320,7 +320,7 @@ static fetch_func_t get_fetch_size_function(const struct fetch_type *type, | |||
320 | } | 320 | } |
321 | 321 | ||
322 | /* Split symbol and offset. */ | 322 | /* Split symbol and offset. */ |
323 | int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) | 323 | int traceprobe_split_symbol_offset(char *symbol, long *offset) |
324 | { | 324 | { |
325 | char *tmp; | 325 | char *tmp; |
326 | int ret; | 326 | int ret; |
@@ -328,13 +328,11 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) | |||
328 | if (!offset) | 328 | if (!offset) |
329 | return -EINVAL; | 329 | return -EINVAL; |
330 | 330 | ||
331 | tmp = strchr(symbol, '+'); | 331 | tmp = strpbrk(symbol, "+-"); |
332 | if (tmp) { | 332 | if (tmp) { |
333 | /* skip sign because kstrtoul doesn't accept '+' */ | 333 | ret = kstrtol(tmp, 0, offset); |
334 | ret = kstrtoul(tmp + 1, 0, offset); | ||
335 | if (ret) | 334 | if (ret) |
336 | return ret; | 335 | return ret; |
337 | |||
338 | *tmp = '\0'; | 336 | *tmp = '\0'; |
339 | } else | 337 | } else |
340 | *offset = 0; | 338 | *offset = 0; |
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index e101c5bb9eda..6a4d3fa94042 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h | |||
@@ -365,7 +365,7 @@ extern int traceprobe_conflict_field_name(const char *name, | |||
365 | extern void traceprobe_update_arg(struct probe_arg *arg); | 365 | extern void traceprobe_update_arg(struct probe_arg *arg); |
366 | extern void traceprobe_free_probe_arg(struct probe_arg *arg); | 366 | extern void traceprobe_free_probe_arg(struct probe_arg *arg); |
367 | 367 | ||
368 | extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset); | 368 | extern int traceprobe_split_symbol_offset(char *symbol, long *offset); |
369 | 369 | ||
370 | /* Sum up total data length for dynamic arraies (strings) */ | 370 | /* Sum up total data length for dynamic arraies (strings) */ |
371 | static nokprobe_inline int | 371 | static nokprobe_inline int |