aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/python.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <[email protected]>2025-03-12 20:31:41 +0000
committerNamhyung Kim <[email protected]>2025-03-18 23:08:45 +0000
commit89aaeaf84231157288035b366cb6300c1c6cac64 (patch)
tree5ef1ecaf363779db5e149332200e69a230e4618e /tools/perf/util/python.c
parentperf python: Don't keep a raw_data pointer to consumed ring buffer space (diff)
downloadkernel-89aaeaf84231157288035b366cb6300c1c6cac64.tar.gz
kernel-89aaeaf84231157288035b366cb6300c1c6cac64.zip
perf python: Check if there is space to copy all the event
The pyrf_event__new() method copies the event obtained from the perf ring buffer to a structure that will then be turned into a python object for further consumption, so it copies perf_event.header.size bytes to its 'event' member: $ pahole -C pyrf_event /tmp/build/perf-tools-next/python/perf.cpython-312-x86_64-linux-gnu.so struct pyrf_event { PyObject ob_base; /* 0 16 */ struct evsel * evsel; /* 16 8 */ struct perf_sample sample; /* 24 312 */ /* XXX last struct has 7 bytes of padding, 2 holes */ /* --- cacheline 5 boundary (320 bytes) was 16 bytes ago --- */ union perf_event event; /* 336 4168 */ /* size: 4504, cachelines: 71, members: 4 */ /* member types with holes: 1, total: 2 */ /* paddings: 1, sum paddings: 7 */ /* last cacheline: 24 bytes */ }; $ It was doing so without checking if the event just obtained has more than that space, fix it. This isn't a proper, final solution, as we need to support larger events, but for the time being we at least bounds check and document it. Fixes: 877108e42b1b9ba6 ("perf tools: Initial python binding") Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Reviewed-by: Ian Rogers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Namhyung Kim <[email protected]>
Diffstat (limited to 'tools/perf/util/python.c')
-rw-r--r--tools/perf/util/python.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 6a03341e1788..f3c05da25b4a 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -476,6 +476,11 @@ static PyObject *pyrf_event__new(const union perf_event *event)
event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
return NULL;
+ // FIXME this better be dynamic or we need to parse everything
+ // before calling perf_mmap__consume(), including tracepoint fields.
+ if (sizeof(pevent->event) < event->header.size)
+ return NULL;
+
ptype = pyrf_event__type[event->header.type];
pevent = PyObject_New(struct pyrf_event, ptype);
if (pevent != NULL)