[PATCH v1] perf parse-events: Avoid segv if PMU lookup fails for legacy cache terms

From: Ian Rogers
Date: Wed Jul 12 2023 - 02:53:06 EST


libfuzzer found the following command could segv:
```
$ perf stat -e cpu/L2,L2/ true
```
This is because the L2 term rewrites the perf_event_attr type to
PERF_TYPE_HW_CACHE which then fails the PMU lookup for the second
legacy cache term.

The new failure is consistent with repeated hardware terms:
```
$ perf stat -e cpu/L2,L2/ true
event syntax error: 'cpu/L2,L2/'
\___ Failed to find PMU for type 3

Initial error:
event syntax error: 'cpu/L2,L2/'
\___ Failed to find PMU for type 3
Run 'perf list' for a list of valid events

Usage: perf stat [<options>] [<command>]

-e, --event <event> event selector. use 'perf list' to list available events
$ perf stat -e cpu/cycles,cycles/ true
event syntax error: 'cpu/cycles,cycles/'
\___ Failed to find PMU for type 0

Initial error:
event syntax error: 'cpu/cycles,cycles/'
\___ Failed to find PMU for type 0
Run 'perf list' for a list of valid events

Usage: perf stat [<options>] [<command>]

-e, --event <event> event selector. use 'perf list' to list available events
```

Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/util/parse-events.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5dcfbf316bf6..acde097e327c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1216,6 +1216,14 @@ static int config_term_pmu(struct perf_event_attr *attr,
if (term->type_term == PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE) {
const struct perf_pmu *pmu = perf_pmus__find_by_type(attr->type);

+ if (!pmu) {
+ char *err_str;
+
+ if (asprintf(&err_str, "Failed to find PMU for type %d", attr->type) >= 0)
+ parse_events_error__handle(err, term->err_term,
+ err_str, /*help=*/NULL);
+ return -EINVAL;
+ }
if (perf_pmu__supports_legacy_cache(pmu)) {
attr->type = PERF_TYPE_HW_CACHE;
return parse_events__decode_legacy_cache(term->config, pmu->type,
--
2.41.0.390.g38632f3daf-goog