aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_kprobe.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r--kernel/trace/trace_kprobe.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 8b27c9849b42..2dec9bcde8b4 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -31,7 +31,6 @@
31#include <linux/perf_event.h> 31#include <linux/perf_event.h>
32#include <linux/stringify.h> 32#include <linux/stringify.h>
33#include <linux/limits.h> 33#include <linux/limits.h>
34#include <linux/uaccess.h>
35#include <asm/bitsperlong.h> 34#include <asm/bitsperlong.h>
36 35
37#include "trace.h" 36#include "trace.h"
@@ -514,8 +513,8 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
514static int kretprobe_dispatcher(struct kretprobe_instance *ri, 513static int kretprobe_dispatcher(struct kretprobe_instance *ri,
515 struct pt_regs *regs); 514 struct pt_regs *regs);
516 515
517/* Check the name is good for event/group */ 516/* Check the name is good for event/group/fields */
518static int check_event_name(const char *name) 517static int is_good_name(const char *name)
519{ 518{
520 if (!isalpha(*name) && *name != '_') 519 if (!isalpha(*name) && *name != '_')
521 return 0; 520 return 0;
@@ -557,7 +556,7 @@ static struct trace_probe *alloc_trace_probe(const char *group,
557 else 556 else
558 tp->rp.kp.pre_handler = kprobe_dispatcher; 557 tp->rp.kp.pre_handler = kprobe_dispatcher;
559 558
560 if (!event || !check_event_name(event)) { 559 if (!event || !is_good_name(event)) {
561 ret = -EINVAL; 560 ret = -EINVAL;
562 goto error; 561 goto error;
563 } 562 }
@@ -567,7 +566,7 @@ static struct trace_probe *alloc_trace_probe(const char *group,
567 if (!tp->call.name) 566 if (!tp->call.name)
568 goto error; 567 goto error;
569 568
570 if (!group || !check_event_name(group)) { 569 if (!group || !is_good_name(group)) {
571 ret = -EINVAL; 570 ret = -EINVAL;
572 goto error; 571 goto error;
573 } 572 }
@@ -648,7 +647,7 @@ static int register_trace_probe(struct trace_probe *tp)
648 } 647 }
649 ret = register_probe_event(tp); 648 ret = register_probe_event(tp);
650 if (ret) { 649 if (ret) {
651 pr_warning("Faild to register probe event(%d)\n", ret); 650 pr_warning("Failed to register probe event(%d)\n", ret);
652 goto end; 651 goto end;
653 } 652 }
654 653
@@ -883,7 +882,7 @@ static int create_trace_probe(int argc, char **argv)
883 int i, ret = 0; 882 int i, ret = 0;
884 int is_return = 0, is_delete = 0; 883 int is_return = 0, is_delete = 0;
885 char *symbol = NULL, *event = NULL, *group = NULL; 884 char *symbol = NULL, *event = NULL, *group = NULL;
886 char *arg, *tmp; 885 char *arg;
887 unsigned long offset = 0; 886 unsigned long offset = 0;
888 void *addr = NULL; 887 void *addr = NULL;
889 char buf[MAX_EVENT_NAME_LEN]; 888 char buf[MAX_EVENT_NAME_LEN];
@@ -992,26 +991,36 @@ static int create_trace_probe(int argc, char **argv)
992 /* parse arguments */ 991 /* parse arguments */
993 ret = 0; 992 ret = 0;
994 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { 993 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
994 /* Increment count for freeing args in error case */
995 tp->nr_args++;
996
995 /* Parse argument name */ 997 /* Parse argument name */
996 arg = strchr(argv[i], '='); 998 arg = strchr(argv[i], '=');
997 if (arg) 999 if (arg) {
998 *arg++ = '\0'; 1000 *arg++ = '\0';
999 else 1001 tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
1002 } else {
1000 arg = argv[i]; 1003 arg = argv[i];
1004 /* If argument name is omitted, set "argN" */
1005 snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
1006 tp->args[i].name = kstrdup(buf, GFP_KERNEL);
1007 }
1001 1008
1002 tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
1003 if (!tp->args[i].name) { 1009 if (!tp->args[i].name) {
1004 pr_info("Failed to allocate argument%d name '%s'.\n", 1010 pr_info("Failed to allocate argument[%d] name.\n", i);
1005 i, argv[i]);
1006 ret = -ENOMEM; 1011 ret = -ENOMEM;
1007 goto error; 1012 goto error;
1008 } 1013 }
1009 tmp = strchr(tp->args[i].name, ':'); 1014
1010 if (tmp) 1015 if (!is_good_name(tp->args[i].name)) {
1011 *tmp = '_'; /* convert : to _ */ 1016 pr_info("Invalid argument[%d] name: %s\n",
1017 i, tp->args[i].name);
1018 ret = -EINVAL;
1019 goto error;
1020 }
1012 1021
1013 if (conflict_field_name(tp->args[i].name, tp->args, i)) { 1022 if (conflict_field_name(tp->args[i].name, tp->args, i)) {
1014 pr_info("Argument%d name '%s' conflicts with " 1023 pr_info("Argument[%d] name '%s' conflicts with "
1015 "another field.\n", i, argv[i]); 1024 "another field.\n", i, argv[i]);
1016 ret = -EINVAL; 1025 ret = -EINVAL;
1017 goto error; 1026 goto error;
@@ -1020,12 +1029,9 @@ static int create_trace_probe(int argc, char **argv)
1020 /* Parse fetch argument */ 1029 /* Parse fetch argument */
1021 ret = parse_probe_arg(arg, tp, &tp->args[i], is_return); 1030 ret = parse_probe_arg(arg, tp, &tp->args[i], is_return);
1022 if (ret) { 1031 if (ret) {
1023 pr_info("Parse error at argument%d. (%d)\n", i, ret); 1032 pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
1024 kfree(tp->args[i].name);
1025 goto error; 1033 goto error;
1026 } 1034 }
1027
1028 tp->nr_args++;
1029 } 1035 }
1030 1036
1031 ret = register_trace_probe(tp); 1037 ret = register_trace_probe(tp);