aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/evsel.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index bfce8bf642fa..ee0fe0dffa71 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -303,6 +303,17 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
303 return 0; 303 return 0;
304} 304}
305 305
306static bool sample_overlap(const union perf_event *event,
307 const void *offset, u64 size)
308{
309 const void *base = event;
310
311 if (offset + size > base + event->header.size)
312 return true;
313
314 return false;
315}
316
306int perf_event__parse_sample(const union perf_event *event, u64 type, 317int perf_event__parse_sample(const union perf_event *event, u64 type,
307 int sample_size, bool sample_id_all, 318 int sample_size, bool sample_id_all,
308 struct perf_sample *data) 319 struct perf_sample *data)
@@ -373,14 +384,29 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
373 } 384 }
374 385
375 if (type & PERF_SAMPLE_CALLCHAIN) { 386 if (type & PERF_SAMPLE_CALLCHAIN) {
387 if (sample_overlap(event, array, sizeof(data->callchain->nr)))
388 return -EFAULT;
389
376 data->callchain = (struct ip_callchain *)array; 390 data->callchain = (struct ip_callchain *)array;
391
392 if (sample_overlap(event, array, data->callchain->nr))
393 return -EFAULT;
394
377 array += 1 + data->callchain->nr; 395 array += 1 + data->callchain->nr;
378 } 396 }
379 397
380 if (type & PERF_SAMPLE_RAW) { 398 if (type & PERF_SAMPLE_RAW) {
381 u32 *p = (u32 *)array; 399 u32 *p = (u32 *)array;
400
401 if (sample_overlap(event, array, sizeof(u32)))
402 return -EFAULT;
403
382 data->raw_size = *p; 404 data->raw_size = *p;
383 p++; 405 p++;
406
407 if (sample_overlap(event, p, data->raw_size))
408 return -EFAULT;
409
384 data->raw_data = p; 410 data->raw_data = p;
385 } 411 }
386 412