Commit 98e1da905cbe64bb023a165c7c01eef5e800609e

Authored by Frederic Weisbecker
1 parent a285412479

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