Commit 98e1da905cbe64bb023a165c7c01eef5e800609e
1 parent
a285412479
Exists in
master
and in
20 other branches
perf tools: Robustify dynamic sample content fetch
Ensure the size of the dynamic fields such as callchains or raw events don't overlap the whole event boundaries. This prevents from dereferencing junk if the given size of the callchain goes too eager. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Reported-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Stephane Eranian <eranian@google.com>
Showing 1 changed file with 26 additions and 0 deletions Side-by-side Diff
tools/perf/util/evsel.c
... | ... | @@ -303,6 +303,17 @@ |
303 | 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 | 317 | int perf_event__parse_sample(const union perf_event *event, u64 type, |
307 | 318 | int sample_size, bool sample_id_all, |
308 | 319 | struct perf_sample *data) |
309 | 320 | |
310 | 321 | |
311 | 322 | |
... | ... | @@ -373,14 +384,29 @@ |
373 | 384 | } |
374 | 385 | |
375 | 386 | if (type & PERF_SAMPLE_CALLCHAIN) { |
387 | + if (sample_overlap(event, array, sizeof(data->callchain->nr))) | |
388 | + return -EFAULT; | |
389 | + | |
376 | 390 | data->callchain = (struct ip_callchain *)array; |
391 | + | |
392 | + if (sample_overlap(event, array, data->callchain->nr)) | |
393 | + return -EFAULT; | |
394 | + | |
377 | 395 | array += 1 + data->callchain->nr; |
378 | 396 | } |
379 | 397 | |
380 | 398 | if (type & PERF_SAMPLE_RAW) { |
381 | 399 | u32 *p = (u32 *)array; |
400 | + | |
401 | + if (sample_overlap(event, array, sizeof(u32))) | |
402 | + return -EFAULT; | |
403 | + | |
382 | 404 | data->raw_size = *p; |
383 | 405 | p++; |
406 | + | |
407 | + if (sample_overlap(event, p, data->raw_size)) | |
408 | + return -EFAULT; | |
409 | + | |
384 | 410 | data->raw_data = p; |
385 | 411 | } |
386 | 412 |