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 | ||
