public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option
@ 2011-01-06 10:08 Han Pingtian
  2011-01-06 10:08 ` Han Pingtian
  0 siblings, 1 reply; 5+ messages in thread
From: Han Pingtian @ 2011-01-06 10:08 UTC (permalink / raw)
  To: linux-kernel


Hi,


I found specifying all tracepoints within one "-e" option to perf top,
separating each other with commas, will trigger a buffer overflow.

The command line is:

./perf to  -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 error messages are:

*** buffer overflow detected ***: ./perf terminated
======= Backtrace: =========
/lib64/libc.so.6(__fortify_fail+0x37)[0x382cefb2c7]
/lib64/libc.so.6[0x382cef91c0]
/lib64/libc.so.6[0x382cef82f4]
./perf[0x424f9e]
./perf[0x425966]
./perf[0x42422b]
./perf[0x424468]
./perf[0x424a30]
./perf[0x41539a]
./perf[0x4056d4]
./perf[0x406126]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x382ce1ec5d]
./perf[0x405409]
======= Memory map: ========
00400000-0051c000 r-xp 00000000 fd:06 4573758                            /home/hpt/temp/linux/perf/linux-2.6/tools/perf/perf
0071b000-00733000 rwxp 0011b000 fd:06 4573758                            /home/hpt/temp/linux/perf/linux-2.6/tools/perf/perf
00733000-00b90000 rwxp 00000000 00:00 0
024dc000-024fd000 rwxp 00000000 00:00 0                                  [heap]
... ...

And I have a patch for fixing this problem. Please review it. Thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option
  2011-01-06 10:08 [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option Han Pingtian
@ 2011-01-06 10:08 ` Han Pingtian
  0 siblings, 0 replies; 5+ messages in thread
From: Han Pingtian @ 2011-01-06 10:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: Han Pingtian

I found when specifying all tracepoints with -e to one of subcommand,
such as 'top', the program will trigger a buffer overflow error, like
this:

*** buffer overflow detected ***: ./perf terminated
======= Backtrace: =========
/lib64/libc.so.6(__fortify_fail+0x37)[0x382cefb2c7]
/lib64/libc.so.6[0x382cef91c0]
/lib64/libc.so.6[0x382cef82f4]
./perf[0x4250ee]
./perf[0x425ab6]
./perf[0x42437b]
./perf[0x4245b8]
./perf[0x424b80]
./perf[0x41548a]
./perf[0x405764]
./perf[0x4061b6]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x382ce1ec5d]
./perf[0x405499]
======= Memory map: ========
00400000-0051d000 r-xp 00000000 fd:06 4573549 /home/hpt/temp/linux/perf/linux-2.6/tools/perf/perf
....
The tracepoints are separated by comma, something like this:

perf top -e ...,kmem:kmalloc,kmem:kfree,kmem:kmem_cache_free,...

This comment will fix this problem.

The root reason of this problem is that store_event_type() is called
with all the events, and will overflow the 'filename' at

    strncat(filename, orgname, strlen(orgname));

The comments will try to call store_event_type() when the event name has
been found out.

Signed-off-by: Han Pingtian <phan@redhat.com>
---
 tools/perf/util/parse-events.c |   62 ++++++++++++++++++++--------------------
 1 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index c305305..7183fce 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -491,6 +491,32 @@ parse_multiple_tracepoint_event(char *sys_name, const char *evt_exp,
 }
 
 
+static int store_event_type(const char *orgname)
+{
+	char filename[PATH_MAX], *c;
+	FILE *file;
+	int id, n;
+
+	sprintf(filename, "%s/", debugfs_path);
+	strncat(filename, orgname, strlen(orgname));
+	strcat(filename, "/id");
+
+	c = strchr(filename, ':');
+	if (c)
+		*c = '/';
+
+	file = fopen(filename, "r");
+	if (!file)
+		return 0;
+	n = fscanf(file, "%i", &id);
+	fclose(file);
+	if (n < 1) {
+		pr_err("cannot store event ID\n");
+		return -EINVAL;
+	}
+	return perf_header__push_event(id, orgname);
+}
+
 static enum event_result parse_tracepoint_event(const char **strp,
 				    struct perf_event_attr *attr)
 {
@@ -533,9 +559,13 @@ static enum event_result parse_tracepoint_event(const char **strp,
 		*strp += strlen(sys_name) + evt_length;
 		return parse_multiple_tracepoint_event(sys_name, evt_name,
 						       flags);
-	} else
+	} else {
+		if (store_event_type(evt_name) < 0)
+			return EVT_FAILED;
+
 		return parse_single_tracepoint_event(sys_name, evt_name,
 						     evt_length, attr, strp);
+	}
 }
 
 static enum event_result
@@ -778,41 +808,11 @@ modifier:
 	return ret;
 }
 
-static int store_event_type(const char *orgname)
-{
-	char filename[PATH_MAX], *c;
-	FILE *file;
-	int id, n;
-
-	sprintf(filename, "%s/", debugfs_path);
-	strncat(filename, orgname, strlen(orgname));
-	strcat(filename, "/id");
-
-	c = strchr(filename, ':');
-	if (c)
-		*c = '/';
-
-	file = fopen(filename, "r");
-	if (!file)
-		return 0;
-	n = fscanf(file, "%i", &id);
-	fclose(file);
-	if (n < 1) {
-		pr_err("cannot store event ID\n");
-		return -EINVAL;
-	}
-	return perf_header__push_event(id, orgname);
-}
-
 int parse_events(const struct option *opt __used, const char *str, int unset __used)
 {
 	struct perf_event_attr attr;
 	enum event_result ret;
 
-	if (strchr(str, ':'))
-		if (store_event_type(str) < 0)
-			return -1;
-
 	for (;;) {
 		if (nr_counters == MAX_COUNTERS)
 			return -1;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option
       [not found] <20110106093922.GB6713@hpt.nay.redhat.com>
@ 2011-01-06 18:30 ` Arnaldo Carvalho de Melo
  2011-01-07  3:16   ` Pingtian Han
  2011-01-07 15:30 ` [tip:perf/core] perf tools: Fix buffer overflow error when specifying all tracepoints tip-bot for Han Pingtian
  1 sibling, 1 reply; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2011-01-06 18:30 UTC (permalink / raw)
  To: Han Pingtian; +Cc: linux-kernel

Em Thu, Jan 06, 2011 at 05:39:22PM +0800, Han Pingtian escreveu:
> I found when specifying all tracepoints with -e to one of subcommand,
> such as 'top', the program will trigger a buffer overflow error, like
> this:
> 
> *** buffer overflow detected ***: ./perf terminated
> ======= Backtrace: =========
<SNIP>
> ....
> The tracepoints are separated by comma, something like this:
> 
> perf top -e ...,kmem:kmalloc,kmem:kfree,kmem:kmem_cache_free,...
> 
> This comment will fix this problem.
> 
> The root reason of this problem is that store_event_type() is called
> with all the events, and will overflow the 'filename' at
> 
>     strncat(filename, orgname, strlen(orgname));
> 
> The comments will try to call store_event_type() when the event name has
> been found out.

s/comments/patch/g, right? Other than that looks fine, applying.

- Arnaldo

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option
  2011-01-06 18:30 ` [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option Arnaldo Carvalho de Melo
@ 2011-01-07  3:16   ` Pingtian Han
  0 siblings, 0 replies; 5+ messages in thread
From: Pingtian Han @ 2011-01-07  3:16 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: linux-kernel

My mistake, it should be 'patch' other than 'comments'. Thanks!

----- Original Message -----
From: "Arnaldo Carvalho de Melo" <acme@infradead.org>
To: "Han Pingtian" <phan@redhat.com>
Cc: linux-kernel@vger.kernel.org
Sent: Friday, January 7, 2011 2:30:12 AM
Subject: Re: [PATCH] perf: fix buffer overflow error caused by specifying	all tracepoints with -e option

Em Thu, Jan 06, 2011 at 05:39:22PM +0800, Han Pingtian escreveu:
> I found when specifying all tracepoints with -e to one of subcommand,
> such as 'top', the program will trigger a buffer overflow error, like
> this:
> 
> *** buffer overflow detected ***: ./perf terminated
> ======= Backtrace: =========
<SNIP>
> ....
> The tracepoints are separated by comma, something like this:
> 
> perf top -e ...,kmem:kmalloc,kmem:kfree,kmem:kmem_cache_free,...
> 
> This comment will fix this problem.
> 
> The root reason of this problem is that store_event_type() is called
> with all the events, and will overflow the 'filename' at
> 
>     strncat(filename, orgname, strlen(orgname));
> 
> The comments will try to call store_event_type() when the event name has
> been found out.

s/comments/patch/g, right? Other than that looks fine, applying.

- Arnaldo

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [tip:perf/core] perf tools: Fix buffer overflow error when specifying all tracepoints
       [not found] <20110106093922.GB6713@hpt.nay.redhat.com>
  2011-01-06 18:30 ` [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option Arnaldo Carvalho de Melo
@ 2011-01-07 15:30 ` tip-bot for Han Pingtian
  1 sibling, 0 replies; 5+ messages in thread
From: tip-bot for Han Pingtian @ 2011-01-07 15:30 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: acme, linux-kernel, hpa, mingo, phan, tglx

Commit-ID:  f006d25a15216a483cec71e886786874f66f9452
Gitweb:     http://git.kernel.org/tip/f006d25a15216a483cec71e886786874f66f9452
Author:     Han Pingtian <phan@redhat.com>
AuthorDate: Thu, 6 Jan 2011 17:39:22 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 6 Jan 2011 18:04:46 -0200

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>
---
 tools/perf/util/parse-events.c |   61 +++++++++++++++++++--------------------
 1 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 649083f..917a0ca 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,
 	return EVT_HANDLED_ALL;
 }
 
+static int store_event_type(const char *orgname)
+{
+	char filename[PATH_MAX], *c;
+	FILE *file;
+	int id, n;
+
+	sprintf(filename, "%s/", debugfs_path);
+	strncat(filename, orgname, strlen(orgname));
+	strcat(filename, "/id");
+
+	c = strchr(filename, ':');
+	if (c)
+		*c = '/';
+
+	file = fopen(filename, "r");
+	if (!file)
+		return 0;
+	n = fscanf(file, "%i", &id);
+	fclose(file);
+	if (n < 1) {
+		pr_err("cannot store event ID\n");
+		return -EINVAL;
+	}
+	return perf_header__push_event(id, orgname);
+}
 
 static enum event_result parse_tracepoint_event(const char **strp,
 				    struct perf_event_attr *attr)
@@ -533,9 +558,13 @@ static enum event_result parse_tracepoint_event(const char **strp,
 		*strp += strlen(sys_name) + evt_length;
 		return parse_multiple_tracepoint_event(sys_name, evt_name,
 						       flags);
-	} else
+	} else {
+		if (store_event_type(evt_name) < 0)
+			return EVT_FAILED;
+
 		return parse_single_tracepoint_event(sys_name, evt_name,
 						     evt_length, attr, strp);
+	}
 }
 
 static enum event_result
@@ -778,41 +807,11 @@ modifier:
 	return ret;
 }
 
-static int store_event_type(const char *orgname)
-{
-	char filename[PATH_MAX], *c;
-	FILE *file;
-	int id, n;
-
-	sprintf(filename, "%s/", debugfs_path);
-	strncat(filename, orgname, strlen(orgname));
-	strcat(filename, "/id");
-
-	c = strchr(filename, ':');
-	if (c)
-		*c = '/';
-
-	file = fopen(filename, "r");
-	if (!file)
-		return 0;
-	n = fscanf(file, "%i", &id);
-	fclose(file);
-	if (n < 1) {
-		pr_err("cannot store event ID\n");
-		return -EINVAL;
-	}
-	return perf_header__push_event(id, orgname);
-}
-
 int parse_events(const struct option *opt __used, const char *str, int unset __used)
 {
 	struct perf_event_attr attr;
 	enum event_result ret;
 
-	if (strchr(str, ':'))
-		if (store_event_type(str) < 0)
-			return -1;
-
 	for (;;) {
 		memset(&attr, 0, sizeof(attr));
 		ret = parse_event_symbols(&str, &attr);

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-01-07 15:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20110106093922.GB6713@hpt.nay.redhat.com>
2011-01-06 18:30 ` [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option Arnaldo Carvalho de Melo
2011-01-07  3:16   ` Pingtian Han
2011-01-07 15:30 ` [tip:perf/core] perf tools: Fix buffer overflow error when specifying all tracepoints tip-bot for Han Pingtian
2011-01-06 10:08 [PATCH] perf: fix buffer overflow error caused by specifying all tracepoints with -e option Han Pingtian
2011-01-06 10:08 ` Han Pingtian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox