return ret;
}
-static int perf_evsel__parse_id_sample(const struct evsel *evsel,
- const union perf_event *event,
+static int perf_evsel__parse_id_sample(const union perf_event *event,
struct perf_sample *sample)
{
+ const struct evsel *evsel = sample->evsel;
u64 type = evsel->core.attr.sample_type;
const __u64 *array = event->sample.array;
bool swapped = evsel->needs_swap;
union u64_swap u;
-
- array += ((event->header.size -
- sizeof(event->header)) / sizeof(u64)) - 1;
+ int i = ((event->header.size - sizeof(event->header)) / sizeof(u64)) - 1;
if (type & PERF_SAMPLE_IDENTIFIER) {
- sample->id = *array;
- array--;
+ if (i < 0)
+ return -EFAULT;
+
+ sample->id = array[i--];
}
if (type & PERF_SAMPLE_CPU) {
- u.val64 = *array;
+ if (i < 0)
+ return -EFAULT;
+
+ u.val64 = array[i--];
if (swapped) {
/* undo swap of u64, then swap on individual u32s */
u.val64 = bswap_64(u.val64);
u.val32[0] = bswap_32(u.val32[0]);
}
-
sample->cpu = u.val32[0];
- array--;
}
if (type & PERF_SAMPLE_STREAM_ID) {
- sample->stream_id = *array;
- array--;
+ if (i < 0)
+ return -EFAULT;
+
+ sample->stream_id = array[i--];
}
if (type & PERF_SAMPLE_ID) {
- sample->id = *array;
- array--;
+ if (i < 0)
+ return -EFAULT;
+
+ sample->id = array[i--];
}
if (type & PERF_SAMPLE_TIME) {
- sample->time = *array;
- array--;
+ if (i < 0)
+ return -EFAULT;
+
+ sample->time = array[i--];
}
if (type & PERF_SAMPLE_TID) {
- u.val64 = *array;
+ if (i < 0)
+ return -EFAULT;
+
+ u.val64 = array[i--];
if (swapped) {
/* undo swap of u64, then swap on individual u32s */
u.val64 = bswap_64(u.val64);
sample->pid = u.val32[0];
sample->tid = u.val32[1];
- array--;
}
return 0;
data->deferred_cookie = event->callchain_deferred.cookie;
- if (evsel->core.attr.sample_id_all)
- perf_evsel__parse_id_sample(evsel, event, data);
-
+ if (evsel->core.attr.sample_id_all) {
+ if (perf_evsel__parse_id_sample(event, data))
+ goto out_efault;
+ }
return 0;
}
if (event->header.type != PERF_RECORD_SAMPLE) {
- if (evsel->core.attr.sample_id_all)
- perf_evsel__parse_id_sample(evsel, event, data);
+ if (evsel->core.attr.sample_id_all) {
+ if (perf_evsel__parse_id_sample(event, data))
+ goto out_efault;
+ }
return 0;
}
if (event->header.type != PERF_RECORD_SAMPLE) {
struct perf_sample data = {
+ .evsel = evsel,
.time = -1ULL,
};
if (!evsel->core.attr.sample_id_all)
return -1;
- if (perf_evsel__parse_id_sample(evsel, event, &data))
+ if (perf_evsel__parse_id_sample(event, &data))
return -1;
*timestamp = data.time;