The following commit has been merged into the perf/core branch of tip: Commit-ID: 8e8714c3d157568b7a769917a5e05573bbaf5af0 Gitweb: https://git.kernel.org/tip/8e8714c3d157568b7a769917a5e05573bbaf5af0 Author: Ian Rogers <irogers@xxxxxxxxxx> AuthorDate: Fri, 25 Oct 2019 11:08:22 -07:00 Committer: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> CommitterDate: Wed, 06 Nov 2019 15:49:39 -03:00 perf tools: Splice events onto evlist even on error If event parsing fails the event list is leaked, instead splice the list onto the out result and let the caller cleanup. An example input for parse_events found by libFuzzer that reproduces this memory leak is 'm{'. Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx> Acked-by: Jiri Olsa <jolsa@xxxxxxxxxx> Cc: Adrian Hunter <adrian.hunter@xxxxxxxxx> Cc: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx> Cc: Alexei Starovoitov <ast@xxxxxxxxxx> Cc: Andi Kleen <ak@xxxxxxxxxxxxxxx> Cc: Daniel Borkmann <daniel@xxxxxxxxxxxxx> Cc: Jin Yao <yao.jin@xxxxxxxxxxxxxxx> Cc: John Garry <john.garry@xxxxxxxxxx> Cc: Kan Liang <kan.liang@xxxxxxxxxxxxxxx> Cc: Mark Rutland <mark.rutland@xxxxxxx> Cc: Martin KaFai Lau <kafai@xxxxxx> Cc: Namhyung Kim <namhyung@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Song Liu <songliubraving@xxxxxx> Cc: Stephane Eranian <eranian@xxxxxxxxxx> Cc: Yonghong Song <yhs@xxxxxx> Cc: bpf@xxxxxxxxxxxxxxx Cc: clang-built-linux@xxxxxxxxxxxxxxxx Cc: netdev@xxxxxxxxxxxxxxx Link: http://lore.kernel.org/lkml/20191025180827.191916-5-irogers@xxxxxxxxxx Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> --- tools/perf/util/parse-events.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index db882f6..d36b812 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1927,15 +1927,20 @@ int parse_events(struct evlist *evlist, const char *str, ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS); perf_pmu__parse_cleanup(); + + if (!ret && list_empty(&parse_state.list)) { + WARN_ONCE(true, "WARNING: event parser found nothing\n"); + return -1; + } + + /* + * Add list to the evlist even with errors to allow callers to clean up. + */ + perf_evlist__splice_list_tail(evlist, &parse_state.list); + if (!ret) { struct evsel *last; - if (list_empty(&parse_state.list)) { - WARN_ONCE(true, "WARNING: event parser found nothing\n"); - return -1; - } - - perf_evlist__splice_list_tail(evlist, &parse_state.list); evlist->nr_groups += parse_state.nr_groups; last = evlist__last(evlist); last->cmdline_group_boundary = true;