aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/evsel.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 09:25:52 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 09:25:52 -0700
commit19504828b4bee5e471bcd35e214bc6fd0d380692 (patch)
tree30d4ffb6783daf9fadd47548c035646d3f0f073e /tools/perf/util/evsel.c
parent57d19e80f459dd845fb3cfeba8e6df8471bac142 (diff)
parent3cb6d1540880e767d911b79eb49578de2190f428 (diff)
downloadkernel_samsung_smdk4412-19504828b4bee5e471bcd35e214bc6fd0d380692.zip
kernel_samsung_smdk4412-19504828b4bee5e471bcd35e214bc6fd0d380692.tar.gz
kernel_samsung_smdk4412-19504828b4bee5e471bcd35e214bc6fd0d380692.tar.bz2
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf tools: Fix sample size bit operations perf tools: Fix ommitted mmap data update on remap watchdog: Change the default timeout and configure nmi watchdog period based on watchdog_thresh watchdog: Disable watchdog when thresh is zero watchdog: Only disable/enable watchdog if neccessary watchdog: Fix rounding bug in get_sample_period() perf tools: Propagate event parse error handling perf tools: Robustify dynamic sample content fetch perf tools: Pre-check sample size before parsing perf tools: Move evlist sample helpers to evlist area perf tools: Remove junk code in mmap size handling perf tools: Check we are able to read the event size on mmap
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r--tools/perf/util/evsel.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index d6fd59b..ee0fe0d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -303,8 +303,20 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
return 0;
}
+static bool sample_overlap(const union perf_event *event,
+ const void *offset, u64 size)
+{
+ const void *base = event;
+
+ if (offset + size > base + event->header.size)
+ return true;
+
+ return false;
+}
+
int perf_event__parse_sample(const union perf_event *event, u64 type,
- bool sample_id_all, struct perf_sample *data)
+ int sample_size, bool sample_id_all,
+ struct perf_sample *data)
{
const u64 *array;
@@ -319,6 +331,9 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
array = event->sample.array;
+ if (sample_size + sizeof(event->header) > event->header.size)
+ return -EFAULT;
+
if (type & PERF_SAMPLE_IP) {
data->ip = event->ip.ip;
array++;
@@ -369,14 +384,29 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
}
if (type & PERF_SAMPLE_CALLCHAIN) {
+ if (sample_overlap(event, array, sizeof(data->callchain->nr)))
+ return -EFAULT;
+
data->callchain = (struct ip_callchain *)array;
+
+ if (sample_overlap(event, array, data->callchain->nr))
+ return -EFAULT;
+
array += 1 + data->callchain->nr;
}
if (type & PERF_SAMPLE_RAW) {
u32 *p = (u32 *)array;
+
+ if (sample_overlap(event, array, sizeof(u32)))
+ return -EFAULT;
+
data->raw_size = *p;
p++;
+
+ if (sample_overlap(event, p, data->raw_size))
+ return -EFAULT;
+
data->raw_data = p;
}