aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2015-03-24 14:58:13 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-03-26 09:52:29 -0400
commit7c27f78a297b54c3c2f5075cb15d33431b7f6333 (patch)
tree20f626ea02fb0590a0946243008f069993bc72d2 /tools
parent6ebad5c101de0d43dafc9aff88bad45819f10470 (diff)
tools lib traceevent: Zero should not be considered "not found" in eval_flag()
Guilherme Cox found that: There is, however, a potential bug if there is an item with code zero that is not the first one in the symbol list, since eval_flag(..) returns 0 when it doesn't find anything. That is, if you have the following enums: enum { FOO_START = 0, FOO_GO = 1, FOO_END = 2 } and then have: __print_symbolic(foo, FOO_GO, "go", FOO_START, "start", FOO_END, "end") If none of the enums are known to pevent, then eval_flag() will return zero, and it will match it to the first item in the list, which would be FOO_GO, which is not zero. Luckily, in most cases, the first element would be zero, and the parsing would match out of sheer luck. Reported-by: Guilherme Cox <cox@computer.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/r/20150324145813.0bfe95ba@gandalf.local.home Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/traceevent/event-parse.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index b6d11eea8a57..6d31b6419d37 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -3615,7 +3615,7 @@ static const struct flag flags[] = {
3615 { "HRTIMER_RESTART", 1 }, 3615 { "HRTIMER_RESTART", 1 },
3616}; 3616};
3617 3617
3618static unsigned long long eval_flag(const char *flag) 3618static long long eval_flag(const char *flag)
3619{ 3619{
3620 int i; 3620 int i;
3621 3621
@@ -3631,7 +3631,7 @@ static unsigned long long eval_flag(const char *flag)
3631 if (strcmp(flags[i].name, flag) == 0) 3631 if (strcmp(flags[i].name, flag) == 0)
3632 return flags[i].value; 3632 return flags[i].value;
3633 3633
3634 return 0; 3634 return -1LL;
3635} 3635}
3636 3636
3637static void print_str_to_seq(struct trace_seq *s, const char *format, 3637static void print_str_to_seq(struct trace_seq *s, const char *format,
@@ -3705,7 +3705,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3705 struct print_flag_sym *flag; 3705 struct print_flag_sym *flag;
3706 struct format_field *field; 3706 struct format_field *field;
3707 struct printk_map *printk; 3707 struct printk_map *printk;
3708 unsigned long long val, fval; 3708 long long val, fval;
3709 unsigned long addr; 3709 unsigned long addr;
3710 char *str; 3710 char *str;
3711 unsigned char *hex; 3711 unsigned char *hex;
@@ -3764,11 +3764,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3764 print = 0; 3764 print = 0;
3765 for (flag = arg->flags.flags; flag; flag = flag->next) { 3765 for (flag = arg->flags.flags; flag; flag = flag->next) {
3766 fval = eval_flag(flag->value); 3766 fval = eval_flag(flag->value);
3767 if (!val && !fval) { 3767 if (!val && fval < 0) {
3768 print_str_to_seq(s, format, len_arg, flag->str); 3768 print_str_to_seq(s, format, len_arg, flag->str);
3769 break; 3769 break;
3770 } 3770 }
3771 if (fval && (val & fval) == fval) { 3771 if (fval > 0 && (val & fval) == fval) {
3772 if (print && arg->flags.delim) 3772 if (print && arg->flags.delim)
3773 trace_seq_puts(s, arg->flags.delim); 3773 trace_seq_puts(s, arg->flags.delim);
3774 print_str_to_seq(s, format, len_arg, flag->str); 3774 print_str_to_seq(s, format, len_arg, flag->str);