mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 16:53:20 -04:00
perf metricgroup: Fix metric expression copy leaks
metricgroup__copy_metric_events() allocates a new metric expression and
duplicates metric_name before linking the expression into the destination
metric event.
Free new_expr when strdup() fails, and free the duplicated metric_name on
the later error paths.
Fixes: b85a4d61d3 ("perf metric: Allow modifiers on metrics")
Signed-off-by: Yu Peng <pengyu@kylinos.cn>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
@@ -1693,8 +1693,10 @@ int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
|
||||
new_expr->metric_expr = old_expr->metric_expr;
|
||||
new_expr->metric_threshold = old_expr->metric_threshold;
|
||||
new_expr->metric_name = strdup(old_expr->metric_name);
|
||||
if (!new_expr->metric_name)
|
||||
if (!new_expr->metric_name) {
|
||||
free(new_expr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
new_expr->metric_unit = old_expr->metric_unit;
|
||||
new_expr->runtime = old_expr->runtime;
|
||||
@@ -1707,6 +1709,7 @@ int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
|
||||
alloc_size = sizeof(*new_expr->metric_refs);
|
||||
new_expr->metric_refs = calloc(nr + 1, alloc_size);
|
||||
if (!new_expr->metric_refs) {
|
||||
zfree(&new_expr->metric_name);
|
||||
free(new_expr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -1723,6 +1726,7 @@ int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
|
||||
alloc_size = sizeof(*new_expr->metric_events);
|
||||
new_expr->metric_events = calloc(nr + 1, alloc_size);
|
||||
if (!new_expr->metric_events) {
|
||||
zfree(&new_expr->metric_name);
|
||||
zfree(&new_expr->metric_refs);
|
||||
free(new_expr);
|
||||
return -ENOMEM;
|
||||
@@ -1733,6 +1737,7 @@ int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
|
||||
evsel = old_expr->metric_events[idx];
|
||||
evsel = evlist__find_evsel(evlist, evsel->core.idx);
|
||||
if (evsel == NULL) {
|
||||
zfree(&new_expr->metric_name);
|
||||
zfree(&new_expr->metric_events);
|
||||
zfree(&new_expr->metric_refs);
|
||||
free(new_expr);
|
||||
|
||||
Reference in New Issue
Block a user