Commit 47473950 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf header: Fix memory leaks when processing feature headers

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: default avatarIan Rogers <irogers@google.com>
Acked-by: default avatarJiri 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.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 1aa79e57
...@@ -2321,6 +2321,7 @@ static int perf_header__read_build_ids(struct perf_header *header, ...@@ -2321,6 +2321,7 @@ static int perf_header__read_build_ids(struct perf_header *header,
#define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \ #define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \
static int process_##__feat(struct feat_fd *ff, void *data __maybe_unused) \ 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); \ ff->ph->env.__feat_env = do_read_string(ff); \
return ff->ph->env.__feat_env ? 0 : -ENOMEM; \ return ff->ph->env.__feat_env ? 0 : -ENOMEM; \
} }
...@@ -4124,6 +4125,7 @@ int perf_event__process_feature(struct perf_session *session, ...@@ -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; struct perf_record_header_feature *fe = (struct perf_record_header_feature *)event;
int type = fe->header.type; int type = fe->header.type;
u64 feat = fe->feat_id; u64 feat = fe->feat_id;
int ret = 0;
if (type < 0 || type >= PERF_RECORD_HEADER_MAX) { if (type < 0 || type >= PERF_RECORD_HEADER_MAX) {
pr_warning("invalid record type %d in pipe-mode\n", type); pr_warning("invalid record type %d in pipe-mode\n", type);
...@@ -4141,11 +4143,13 @@ int perf_event__process_feature(struct perf_session *session, ...@@ -4141,11 +4143,13 @@ int perf_event__process_feature(struct perf_session *session,
ff.size = event->header.size - sizeof(*fe); ff.size = event->header.size - sizeof(*fe);
ff.ph = &session->header; ff.ph = &session->header;
if (feat_ops[feat].process(&ff, NULL)) if (feat_ops[feat].process(&ff, NULL)) {
return -1; ret = -1;
goto out;
}
if (!feat_ops[feat].print || !tool->show_feat_hdr) if (!feat_ops[feat].print || !tool->show_feat_hdr)
return 0; goto out;
if (!feat_ops[feat].full_only || if (!feat_ops[feat].full_only ||
tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) { tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) {
...@@ -4154,8 +4158,9 @@ int perf_event__process_feature(struct perf_session *session, ...@@ -4154,8 +4158,9 @@ int perf_event__process_feature(struct perf_session *session,
fprintf(stdout, "# %s info available, use -I to display\n", fprintf(stdout, "# %s info available, use -I to display\n",
feat_ops[feat].name); feat_ops[feat].name);
} }
out:
return 0; free_event_desc(ff.events);
return ret;
} }
size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment