Skip to content

Commit 4747395

Browse files
captain5050acmel
authored andcommitted
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: Ian Rogers <[email protected]> Acked-by: Jiri Olsa <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Link: http://lore.kernel.org/lkml/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 1aa79e5 commit 4747395

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

tools/perf/util/header.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,6 +2321,7 @@ static int perf_header__read_build_ids(struct perf_header *header,
23212321
#define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \
23222322
static int process_##__feat(struct feat_fd *ff, void *data __maybe_unused) \
23232323
{\
2324+
free(ff->ph->env.__feat_env); \
23242325
ff->ph->env.__feat_env = do_read_string(ff); \
23252326
return ff->ph->env.__feat_env ? 0 : -ENOMEM; \
23262327
}
@@ -4124,6 +4125,7 @@ int perf_event__process_feature(struct perf_session *session,
41244125
struct perf_record_header_feature *fe = (struct perf_record_header_feature *)event;
41254126
int type = fe->header.type;
41264127
u64 feat = fe->feat_id;
4128+
int ret = 0;
41274129

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

4144-
if (feat_ops[feat].process(&ff, NULL))
4145-
return -1;
4146+
if (feat_ops[feat].process(&ff, NULL)) {
4147+
ret = -1;
4148+
goto out;
4149+
}
41464150

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

41504154
if (!feat_ops[feat].full_only ||
41514155
tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) {
@@ -4154,8 +4158,9 @@ int perf_event__process_feature(struct perf_session *session,
41544158
fprintf(stdout, "# %s info available, use -I to display\n",
41554159
feat_ops[feat].name);
41564160
}
4157-
4158-
return 0;
4161+
out:
4162+
free_event_desc(ff.events);
4163+
return ret;
41594164
}
41604165

41614166
size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp)

0 commit comments

Comments
 (0)