diff options
author | Ingo Molnar <mingo@elte.hu> | 2011-05-22 10:07:37 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-05-22 10:10:01 +0200 |
commit | 3ac1bbcf13c56a19927df670f429eb0c3c11f8e5 (patch) | |
tree | 693e2b7f1a9cb0c6ed6d44375e370e1ae08c7ac9 /tools/perf/util/evsel.c | |
parent | a2d063ac216c1618bfc2b4d40b7176adffa63511 (diff) | |
parent | 5538becaec9ca2ff21e7826372941dc46f498487 (diff) | |
download | op-kernel-dev-3ac1bbcf13c56a19927df670f429eb0c3c11f8e5.zip op-kernel-dev-3ac1bbcf13c56a19927df670f429eb0c3c11f8e5.tar.gz |
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.c | 32 |
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; } |