From: Ian Rogers irogers@google.com
[ Upstream commit 94725994cfd768b9ee1bd06f15c252694b1e9b89 ]
If perf_event_open() fails the fd is opened but it is only freed by closing (not by delete).
Typically when an open fails you don't call close and so this results in a memory leak. To avoid this, add a close when open fails.
Signed-off-by: Ian Rogers irogers@google.com Reviewed-By: Kajol Jain kjain@linux.ibm.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Anshuman Khandual anshuman.khandual@arm.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rob Herring robh@kernel.org Cc: Stephane Eranian eranian@google.com Link: https://lore.kernel.org/r/20220609052355.1300162-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/perf/evsel.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c index 210ea7c06ce8..acf8a215dca3 100644 --- a/tools/lib/perf/evsel.c +++ b/tools/lib/perf/evsel.c @@ -149,23 +149,30 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus, int fd, group_fd, *evsel_fd;
evsel_fd = FD(evsel, idx, thread); - if (evsel_fd == NULL) - return -EINVAL; + if (evsel_fd == NULL) { + err = -EINVAL; + goto out; + }
err = get_group_fd(evsel, idx, thread, &group_fd); if (err < 0) - return err; + goto out;
fd = sys_perf_event_open(&evsel->attr, threads->map[thread].pid, cpu, group_fd, 0);
- if (fd < 0) - return -errno; + if (fd < 0) { + err = -errno; + goto out; + }
*evsel_fd = fd; } } +out: + if (err) + perf_evsel__close(evsel);
return err; }