aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/evsel.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-05-22 10:07:37 +0200
committerIngo Molnar <mingo@elte.hu>2011-05-22 10:10:01 +0200
commit3ac1bbcf13c56a19927df670f429eb0c3c11f8e5 (patch)
tree693e2b7f1a9cb0c6ed6d44375e370e1ae08c7ac9 /tools/perf/util/evsel.c
parenta2d063ac216c1618bfc2b4d40b7176adffa63511 (diff)
parent5538becaec9ca2ff21e7826372941dc46f498487 (diff)
downloadkernel_samsung_smdk4412-3ac1bbcf13c56a19927df670f429eb0c3c11f8e5.zip
kernel_samsung_smdk4412-3ac1bbcf13c56a19927df670f429eb0c3c11f8e5.tar.gz
kernel_samsung_smdk4412-3ac1bbcf13c56a19927df670f429eb0c3c11f8e5.tar.bz2
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into perf/urgent
Conflicts: tools/perf/builtin-top.c Semantic conflict: util/include/linux/list.h # fix prefetch.h removal fallout Signed-off-by: Ingo Molnar <mingo@elte.hu>
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;
}