All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] perf tools: Fix a problem when opening old perf.data with different byte order
@ 2015-06-17  3:40 Wang Nan
  2015-06-17  8:46 ` Jiri Olsa
  0 siblings, 1 reply; 5+ messages in thread
From: Wang Nan @ 2015-06-17  3:40 UTC (permalink / raw)
  To: acme, namhyung, masami.hiramatsu.pt, a.p.zijlstra, mingo, jolsa
  Cc: linux-kernel, pi3orama, lizefan

Following error occurs when trying to use 'perf report' on x86_64 to
cross analysis a perf.data generated by an old perf on a big-endian
machine:

 # perf report
 *** Error in `/home/w00229757/perf': free(): invalid next size (fast): 0x00000000032c99f0 ***
 ======= Backtrace: =========
 /lib64/libc.so.6(+0x6eeef)[0x7ff6ff7e2eef]
 /lib64/libc.so.6(+0x78cae)[0x7ff6ff7eccae]
 /lib64/libc.so.6(+0x79987)[0x7ff6ff7ed987]
 /path/to/perf[0x4ac734]
 /path/to/perf[0x4ac829]
 /path/to/perf(perf_header__process_sections+0x129)[0x4ad2c9]
 /path/to/perf(perf_session__read_header+0x2e1)[0x4ad9e1]
 /path/to/perf(perf_session__new+0x168)[0x4bd458]
 /path/to/perf(cmd_report+0xfa0)[0x43eb70]
 /path/to/perf[0x47adc3]
 /path/to/perf(main+0x5f6)[0x42fd06]
 /lib64/libc.so.6(__libc_start_main+0xf5)[0x7ff6ff795bd5]
 /path/to/perf[0x42fe35]
 ======= Memory map: ========
 [SNIP]

The bug is in perf_event__attr_swap(). It swaps all fields in
'struct perf_event_attr' without checking whether the swapped field
exist or not. In addition, in read_event_desc() allocs memory for attr
according to size read from perf.data. Therefore, if the perf.data is
collected by an old perf (without aux_watermark, for example),
when perf_event__attr_swap() swaping attr->aux_watermark it destroy
malloc's metadata.

This patch introduces boundary checking in perf_event__attr_swap(). It
adds macros bswap_field_64 and bswap_field_32 into
perf_event__attr_swap() to make it only swap exist fields.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
---
 tools/perf/util/session.c | 40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 88d87bf..d51ba31 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -517,20 +517,32 @@ void perf_event__attr_swap(struct perf_event_attr *attr)
 {
 	attr->type		= bswap_32(attr->type);
 	attr->size		= bswap_32(attr->size);
-	attr->config		= bswap_64(attr->config);
-	attr->sample_period	= bswap_64(attr->sample_period);
-	attr->sample_type	= bswap_64(attr->sample_type);
-	attr->read_format	= bswap_64(attr->read_format);
-	attr->wakeup_events	= bswap_32(attr->wakeup_events);
-	attr->bp_type		= bswap_32(attr->bp_type);
-	attr->bp_addr		= bswap_64(attr->bp_addr);
-	attr->bp_len		= bswap_64(attr->bp_len);
-	attr->branch_sample_type = bswap_64(attr->branch_sample_type);
-	attr->sample_regs_user	 = bswap_64(attr->sample_regs_user);
-	attr->sample_stack_user  = bswap_32(attr->sample_stack_user);
-	attr->aux_watermark	 = bswap_32(attr->aux_watermark);
-
-	swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64));
+#define bswap_safe(f) \
+	(attr->size > offsetof(struct perf_event_attr, f))
+#define bswap_field(f, sz) 			\
+do { 						\
+	if (bswap_safe(f))			\
+		attr->f = bswap_##sz(attr->f);	\
+} while(0)
+#define bswap_field_32(f) bswap_field(f, 32)
+#define bswap_field_64(f) bswap_field(f, 64)
+
+	bswap_field_64(config);
+	bswap_field_64(sample_period);
+	bswap_field_64(sample_type);
+	bswap_field_64(read_format);
+	bswap_field_32(wakeup_events);
+	bswap_field_32(bp_type);
+	bswap_field_64(bp_addr);
+	bswap_field_64(bp_len);
+	bswap_field_64(branch_sample_type);
+	bswap_field_64(sample_regs_user);
+	bswap_field_32(sample_stack_user);
+	bswap_field_32(aux_watermark);
+
+	if (bswap_safe(read_format))
+		swap_bitfield((u8 *) (&attr->read_format + 1),
+			      sizeof(u64));
 }
 
 static void perf_event__hdr_attr_swap(union perf_event *event,
-- 
1.8.3.4


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

end of thread, other threads:[~2015-06-18  8:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-17  3:40 [PATCH] perf tools: Fix a problem when opening old perf.data with different byte order Wang Nan
2015-06-17  8:46 ` Jiri Olsa
2015-06-17  9:56   ` [PATCH v2] " Wang Nan
2015-06-17 18:24     ` Jiri Olsa
2015-06-18  8:16     ` [tip:perf/core] " tip-bot for Wang Nan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.