perf tools: Robustify dynamic sample content fetch
[linux-2.6.git] / tools / perf / util / evsel.c
index bfce8bf..ee0fe0d 100644 (file)
@@ -303,6 +303,17 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
        return 0;
 }
 
+static bool sample_overlap(const union perf_event *event,
+                          const void *offset, u64 size)
+{
+       const void *base = event;
+
+       if (offset + size > base + event->header.size)
+               return true;
+
+       return false;
+}
+
 int perf_event__parse_sample(const union perf_event *event, u64 type,
                             int sample_size, bool sample_id_all,
                             struct perf_sample *data)
@@ -373,14 +384,29 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
        }
 
        if (type & PERF_SAMPLE_CALLCHAIN) {
+               if (sample_overlap(event, array, sizeof(data->callchain->nr)))
+                       return -EFAULT;
+
                data->callchain = (struct ip_callchain *)array;
+
+               if (sample_overlap(event, array, data->callchain->nr))
+                       return -EFAULT;
+
                array += 1 + data->callchain->nr;
        }
 
        if (type & PERF_SAMPLE_RAW) {
                u32 *p = (u32 *)array;
+
+               if (sample_overlap(event, array, sizeof(u32)))
+                       return -EFAULT;
+
                data->raw_size = *p;
                p++;
+
+               if (sample_overlap(event, p, data->raw_size))
+                       return -EFAULT;
+
                data->raw_data = p;
        }