Commit 5b10c18d authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo
Browse files

perf parse-events: Avoid SEGV if PMU lookup fails for legacy cache terms



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

Committer testing:

Before:

  $ perf stat -e cpu/L2,L2/ true
  Segmentation fault (core dumped)
  $

After:

  $ 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
  $

Fixes: 6fd1e519 ("perf parse-events: Support PMUs for legacy cache events")
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Link: https://lore.kernel.org/r/20230712065250.1450306-1-irogers@google.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 4b966791
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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,