Skip to content

Commit

Permalink
perf header: Fix memory leaks when processing feature headers
Browse files Browse the repository at this point in the history
These leaks were found with leak sanitizer running "perf pipe recording
and injection test".

In pipe mode feat_fd may hold onto an events struct that needs freeing.

When string features are processed they may overwrite an already created
string, so free this before the overwrite.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20211118201730.2302927-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Ian Rogers authored and Arnaldo Carvalho de Melo committed Dec 7, 2021
1 parent 1aa79e5 commit 4747395
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions tools/perf/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -2321,6 +2321,7 @@ static int perf_header__read_build_ids(struct perf_header *header,
#define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \
static int process_##__feat(struct feat_fd *ff, void *data __maybe_unused) \
{\
free(ff->ph->env.__feat_env); \
ff->ph->env.__feat_env = do_read_string(ff); \
return ff->ph->env.__feat_env ? 0 : -ENOMEM; \
}
Expand Down Expand Up @@ -4124,6 +4125,7 @@ int perf_event__process_feature(struct perf_session *session,
struct perf_record_header_feature *fe = (struct perf_record_header_feature *)event;
int type = fe->header.type;
u64 feat = fe->feat_id;
int ret = 0;

if (type < 0 || type >= PERF_RECORD_HEADER_MAX) {
pr_warning("invalid record type %d in pipe-mode\n", type);
Expand All @@ -4141,11 +4143,13 @@ int perf_event__process_feature(struct perf_session *session,
ff.size = event->header.size - sizeof(*fe);
ff.ph = &session->header;

if (feat_ops[feat].process(&ff, NULL))
return -1;
if (feat_ops[feat].process(&ff, NULL)) {
ret = -1;
goto out;
}

if (!feat_ops[feat].print || !tool->show_feat_hdr)
return 0;
goto out;

if (!feat_ops[feat].full_only ||
tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) {
Expand All @@ -4154,8 +4158,9 @@ int perf_event__process_feature(struct perf_session *session,
fprintf(stdout, "# %s info available, use -I to display\n",
feat_ops[feat].name);
}

return 0;
out:
free_event_desc(ff.events);
return ret;
}

size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp)
Expand Down

0 comments on commit 4747395

Please sign in to comment.