diff options
-rw-r--r-- | tools/perf/util/evsel.c | 26 |
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 | ||
306 | static 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 | |||
306 | int perf_event__parse_sample(const union perf_event *event, u64 type, | 317 | int 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 | ||