[PATCH v2 08/16] perf python: Check counts_values size in set_values
From: Ian Rogers
Date: Wed Jun 24 2026 - 01:19:57 EST
The set_values function incorrectly assumed the list contained exactly
5 elements. Add a check to prevent out-of-bounds access.
Fixes: 877108e42b1b ("perf tools: Initial python binding")
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/util/python.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 550f1e7d1449..c6c729808a0f 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -1881,11 +1881,11 @@ static void pyrf_counts_values__delete(struct pyrf_counts_values *pcounts_values
0, help }
static PyMemberDef pyrf_counts_values_members[] = {
- counts_values_member_def(val, T_ULONG, "Value of event"),
- counts_values_member_def(ena, T_ULONG, "Time for which enabled"),
- counts_values_member_def(run, T_ULONG, "Time for which running"),
- counts_values_member_def(id, T_ULONG, "Unique ID for an event"),
- counts_values_member_def(lost, T_ULONG, "Num of lost samples"),
+ counts_values_member_def(val, T_ULONGLONG, "Value of event"),
+ counts_values_member_def(ena, T_ULONGLONG, "Time for which enabled"),
+ counts_values_member_def(run, T_ULONGLONG, "Time for which running"),
+ counts_values_member_def(id, T_ULONGLONG, "Unique ID for an event"),
+ counts_values_member_def(lost, T_ULONGLONG, "Num of lost samples"),
{ .name = NULL, },
};
@@ -1895,8 +1895,15 @@ static PyObject *pyrf_counts_values_get_values(struct pyrf_counts_values *self,
if (!vals)
return NULL;
- for (int i = 0; i < 5; i++)
- PyList_SetItem(vals, i, PyLong_FromLong(self->values.values[i]));
+ for (int i = 0; i < 5; i++) {
+ PyObject *val = PyLong_FromUnsignedLongLong(self->values.values[i]);
+
+ if (!val) {
+ Py_DECREF(vals);
+ return NULL;
+ }
+ PyList_SetItem(vals, i, val);
+ }
return vals;
}
@@ -1913,13 +1920,23 @@ static int pyrf_counts_values_set_values(struct pyrf_counts_values *self, PyObje
}
size = PyList_Size(list);
+ if (size != 5) {
+ PyErr_SetString(PyExc_ValueError, "List must have exactly 5 entries");
+ return -1;
+ }
+
for (Py_ssize_t i = 0; i < size; i++) {
+ unsigned long long val;
+
item = PyList_GetItem(list, i);
if (!PyLong_Check(item)) {
PyErr_SetString(PyExc_TypeError, "List members should be numbers");
return -1;
}
- self->values.values[i] = PyLong_AsLong(item);
+ val = PyLong_AsUnsignedLongLong(item);
+ if (val == (unsigned long long)-1 && PyErr_Occurred())
+ return -1;
+ self->values.values[i] = val;
}
return 0;
--
2.55.0.rc0.799.gd6f94ed593-goog