aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorHan Pingtian <phan@redhat.com>2011-01-06 04:39:22 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-01-06 15:04:46 -0500
commitf006d25a15216a483cec71e886786874f66f9452 (patch)
tree66420a0098c774f4d8c29bb43f81e2ba967c59cb /tools/perf/util
parent4b95f135f606c87e4056b6d7fd3c5781c818858b (diff)
perf tools: Fix buffer overflow error when specifying all tracepoints
I found when specifying all tracepoints with -e to one of subcommand, such as 'stat', the program will trigger a buffer overflow error, like this: *** buffer overflow detected ***: ./perf terminated ======= Backtrace: ========= /lib64/libc.so.6(__fortify_fail+0x37)[0x382cefb2c7] .... The tracepoints are separated by comma, something like this: $ perf stat -a -e `perf list |grep Tracepoint|awk -F'[' '{gsub(/[[:space:]]+/,"",$1);array[FNR]=$1}END{outputs=array[1];for (i=2;i<=FNR;i++){ outputs=outputs "," array[i];};print outputs}'` The root reason of this problem is that store_event_type() is called for all events, and will overflow the 'filename' at: strncat(filename, orgname, strlen(orgname)); This patch fixes it by calling store_event_type() only when the event name has been found. LKML-Reference: <20110106093922.GB6713@hpt.nay.redhat.com> Signed-off-by: Han Pingtian <phan@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/parse-events.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 649083f27e08..917a0ca521c1 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -490,6 +490,31 @@ parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp,
490 return EVT_HANDLED_ALL; 490 return EVT_HANDLED_ALL;
491} 491}
492 492
493static int store_event_type(const char *orgname)
494{
495 char filename[PATH_MAX], *c;
496 FILE *file;
497 int id, n;
498
499 sprintf(filename, "%s/", debugfs_path);
500 strncat(filename, orgname, strlen(orgname));
501 strcat(filename, "/id");
502
503 c = strchr(filename, ':');
504 if (c)
505 *c = '/';
506
507 file = fopen(filename, "r");
508 if (!file)
509 return 0;
510 n = fscanf(file, "%i", &id);
511 fclose(file);
512 if (n < 1) {
513 pr_err("cannot store event ID\n");
514 return -EINVAL;
515 }
516 return perf_header__push_event(id, orgname);
517}
493 518
494static enum event_result parse_tracepoint_event(const char **strp, 519static enum event_result parse_tracepoint_event(const char **strp,
495 struct perf_event_attr *attr) 520 struct perf_event_attr *attr)
@@ -533,9 +558,13 @@ static enum event_result parse_tracepoint_event(const char **strp,
533 *strp += strlen(sys_name) + evt_length; 558 *strp += strlen(sys_name) + evt_length;
534 return parse_multiple_tracepoint_event(sys_name, evt_name, 559 return parse_multiple_tracepoint_event(sys_name, evt_name,
535 flags); 560 flags);
536 } else 561 } else {
562 if (store_event_type(evt_name) < 0)
563 return EVT_FAILED;
564
537 return parse_single_tracepoint_event(sys_name, evt_name, 565 return parse_single_tracepoint_event(sys_name, evt_name,
538 evt_length, attr, strp); 566 evt_length, attr, strp);
567 }
539} 568}
540 569
541static enum event_result 570static enum event_result
@@ -778,41 +807,11 @@ modifier:
778 return ret; 807 return ret;
779} 808}
780 809
781static int store_event_type(const char *orgname)
782{
783 char filename[PATH_MAX], *c;
784 FILE *file;
785 int id, n;
786
787 sprintf(filename, "%s/", debugfs_path);
788 strncat(filename, orgname, strlen(orgname));
789 strcat(filename, "/id");
790
791 c = strchr(filename, ':');
792 if (c)
793 *c = '/';
794
795 file = fopen(filename, "r");
796 if (!file)
797 return 0;
798 n = fscanf(file, "%i", &id);
799 fclose(file);
800 if (n < 1) {
801 pr_err("cannot store event ID\n");
802 return -EINVAL;
803 }
804 return perf_header__push_event(id, orgname);
805}
806
807int parse_events(const struct option *opt __used, const char *str, int unset __used) 810int parse_events(const struct option *opt __used, const char *str, int unset __used)
808{ 811{
809 struct perf_event_attr attr; 812 struct perf_event_attr attr;
810 enum event_result ret; 813 enum event_result ret;
811 814
812 if (strchr(str, ':'))
813 if (store_event_type(str) < 0)
814 return -1;
815
816 for (;;) { 815 for (;;) {
817 memset(&attr, 0, sizeof(attr)); 816 memset(&attr, 0, sizeof(attr));
818 ret = parse_event_symbols(&str, &attr); 817 ret = parse_event_symbols(&str, &attr);