aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/evsel.c
diff options
context:
space:
mode:
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 d6fd59beb860..ee0fe0dffa71 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,
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 bool sample_id_all, struct perf_sample *data) 318 int sample_size, bool sample_id_all,
319 struct perf_sample *data)
308{ 320{
309 const u64 *array; 321 const u64 *array;
310 322
@@ -319,6 +331,9 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
319 331
320 array = event->sample.array; 332 array = event->sample.array;
321 333
334 if (sample_size + sizeof(event->header) > event->header.size)
335 return -EFAULT;
336
322 if (type & PERF_SAMPLE_IP) { 337 if (type & PERF_SAMPLE_IP) {
323 data->ip = event->ip.ip; 338 data->ip = event->ip.ip;
324 array++; 339 array++;
@@ -369,14 +384,29 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
369 } 384 }
370 385
371 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
372 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
373 array += 1 + data->callchain->nr; 395 array += 1 + data->callchain->nr;
374 } 396 }
375 397
376 if (type & PERF_SAMPLE_RAW) { 398 if (type & PERF_SAMPLE_RAW) {
377 u32 *p = (u32 *)array; 399 u32 *p = (u32 *)array;
400
401 if (sample_overlap(event, array, sizeof(u32)))
402 return -EFAULT;
403
378 data->raw_size = *p; 404 data->raw_size = *p;
379 p++; 405 p++;
406
407 if (sample_overlap(event, p, data->raw_size))
408 return -EFAULT;
409
380 data->raw_data = p; 410 data->raw_data = p;
381 } 411 }
382 412