lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 19 Apr 2016 19:32:11 -0700
From:	Chris Phlipot <cphlipot0@...il.com>
To:	acme@...nel.org, mingo@...hat.com, peterz@...radead.org
Cc:	linux-kernel@...r.kernel.org, Chris Phlipot <cphlipot0@...il.com>
Subject: [PATCH] perf script: fix segfault when printing callchains using builtin-script

This fixes a bug caused by an unitialized callchain cursor. The crash
frist appeared in:
6f736735e30f ("perf evsel: Require that callchains be resolved before
calling fprintf_{sym,callchain}")

The callchain cursor is a struct that contains pointers, that when
uninitialized will cause unpredictable behavior (usually a crash)
when trying to append to the callchain.

The existing implementation has the following issues:
1. The callchain cursor used is not initialized, resulting in
	unpredictable behavior when used.
2. The cursor is declared on the stack. Even if it is properly initalized,
	the implmentation will leak memory when the function returns,
	since all the references to the callchain_nodes allocated by
	callchain_cursor_append will be lost when the cursor goes out of
	scope.
3. Storing the cursor on the stack is inefficient. Even if memory is
	properly freed when it goes out of scope, a performance penalty
	will be incurred due to reallocation of callchain nodes.
	callchain_cursor_append is designed to avoid these reallocations
	when an existing cursor is reused.

This patch fixes the crash by replacing cursor_callchain with a reference
to the global callchain_cursor which also resolves all 3 issues mentioned
above.

How to reproduce the crash:
$ perf record --call-graph=dwarf stress -t 1 -c 1
$ perf script > /dev/null
Segfault

Signed-off-by: Chris Phlipot <cphlipot0@...il.com>
---
 tools/perf/builtin-script.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 5099740..f43b0c6 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -570,12 +570,12 @@ static void print_sample_bts(struct perf_sample *sample,
 	/* print branch_from information */
 	if (PRINT_FIELD(IP)) {
 		unsigned int print_opts = output[attr->type].print_ip_opts;
-		struct callchain_cursor *cursor = NULL, cursor_callchain;
+		struct callchain_cursor *cursor = NULL;
 
 		if (symbol_conf.use_callchain && sample->callchain &&
-		    thread__resolve_callchain(al->thread, &cursor_callchain, evsel,
+		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
 					      sample, NULL, NULL, scripting_max_stack) == 0)
-			cursor = &cursor_callchain;
+			cursor = &callchain_cursor;
 
 		if (cursor == NULL) {
 			putchar(' ');
@@ -789,12 +789,12 @@ static void process_event(struct perf_script *script,
 		printf("%16" PRIu64, sample->weight);
 
 	if (PRINT_FIELD(IP)) {
-		struct callchain_cursor *cursor = NULL, cursor_callchain;
+		struct callchain_cursor *cursor = NULL;
 
 		if (symbol_conf.use_callchain && sample->callchain &&
-		    thread__resolve_callchain(al->thread, &cursor_callchain, evsel,
+		    thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
 					      sample, NULL, NULL, scripting_max_stack) == 0)
-			cursor = &cursor_callchain;
+			cursor = &callchain_cursor;
 
 		putchar(cursor ? '\n' : ' ');
 		sample__fprintf_sym(sample, al, 0, output[attr->type].print_ip_opts, cursor, stdout);
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ