summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2026-06-10 22:45:08 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-06-17 08:29:07 -0300
commit542e88a4c6f7b6edd1326ce767d4cb3c2ea9d61d (patch)
tree3faaee3280b033921d23b353abdb9e62317fe348
parent4a7500d772fe59653053db22ca83c9e2232b22e1 (diff)
downloadlwn-542e88a4c6f7b6edd1326ce767d4cb3c2ea9d61d.tar.gz
lwn-542e88a4c6f7b6edd1326ce767d4cb3c2ea9d61d.zip
perf cs-etm: Reject CPU IDs that would overflow signed comparison
metadata[j][CS_ETM_CPU] is a u64 from perf.data, but the comparison with max_cpu casts it to (int). A crafted value like 0xFFFFFFFF becomes -1 after the cast, which compares less than max_cpu (0), so the queue array is never sized to accommodate it. When the value is later passed to cs_etm__get_queue(), it indexes queue_array with the original large value, causing an out-of-bounds access. Validate that CS_ETM_CPU fits in an int before using it in the signed comparison. Fixes: 57880a7966be510c ("perf: cs-etm: Allocate queues for all CPUs") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Cc: James Clark <james.clark@arm.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/cs-etm.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 5e92359f51a7..0927b0b9c06b 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -6,6 +6,7 @@
* Author: Mathieu Poirier <mathieu.poirier@linaro.org>
*/
+#include <limits.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/coresight-pmu.h>
@@ -3468,7 +3469,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
goto err_free_metadata;
}
- if ((int) metadata[j][CS_ETM_CPU] > max_cpu)
+ /* CPU id comes from perf.data and must fit max_cpu + 1 without overflow */
+ if (metadata[j][CS_ETM_CPU] >= INT_MAX) {
+ err = -EINVAL;
+ goto err_free_metadata;
+ }
+
+ if ((int)metadata[j][CS_ETM_CPU] > max_cpu)
max_cpu = metadata[j][CS_ETM_CPU];
}