mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
perf kwork: Fix address sanitizer issues
There is a double free in the record array due to how parse_options will mutate the array. Fix by keeping an array that isn't mutated. Ensure kwork_usage is freed on all paths. Signed-off-by: Ian Rogers <irogers@google.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
fdec0a81ca
commit
ca426c0f6e
|
|
@ -2258,7 +2258,7 @@ static void setup_event_list(struct perf_kwork *kwork,
|
|||
static int perf_kwork__record(struct perf_kwork *kwork,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
const char **rec_argv;
|
||||
const char **rec_argv, **to_free = NULL;
|
||||
unsigned int rec_argc, i, j;
|
||||
struct kwork_class *class;
|
||||
int ret;
|
||||
|
|
@ -2295,16 +2295,27 @@ static int perf_kwork__record(struct perf_kwork *kwork,
|
|||
|
||||
BUG_ON(i != rec_argc);
|
||||
|
||||
/* Save the pointers as the array will be mutated by cmd_record. */
|
||||
to_free = calloc(rec_argc + 1, sizeof(char *));
|
||||
if (to_free == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
pr_debug("record comm: ");
|
||||
for (j = 0; j < rec_argc; j++)
|
||||
for (j = 0; j < rec_argc; j++) {
|
||||
pr_debug("%s ", rec_argv[j]);
|
||||
to_free[j] = rec_argv[j];
|
||||
}
|
||||
pr_debug("\n");
|
||||
|
||||
ret = cmd_record(i, rec_argv);
|
||||
|
||||
EXIT:
|
||||
for (i = 0; i < rec_argc; i++)
|
||||
free((void *)rec_argv[i]);
|
||||
free((void *)(to_free ? to_free[i] : rec_argv[i]));
|
||||
|
||||
free(to_free);
|
||||
free(rec_argv);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2447,6 +2458,7 @@ int cmd_kwork(int argc, const char **argv)
|
|||
const char *const kwork_subcommands[] = {
|
||||
"record", "report", "latency", "timehist", "top", NULL
|
||||
};
|
||||
int ret = 0;
|
||||
|
||||
perf_tool__init(&kwork.tool, /*ordered_events=*/true);
|
||||
kwork.tool.mmap = perf_event__process_mmap;
|
||||
|
|
@ -2463,7 +2475,7 @@ int cmd_kwork(int argc, const char **argv)
|
|||
|
||||
if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) {
|
||||
setup_event_list(&kwork, kwork_options, kwork_usage);
|
||||
return perf_kwork__record(&kwork, argc, argv);
|
||||
ret = perf_kwork__record(&kwork, argc, argv);
|
||||
} else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) {
|
||||
kwork.sort_order = default_report_sort_order;
|
||||
if (argc > 1) {
|
||||
|
|
@ -2474,7 +2486,7 @@ int cmd_kwork(int argc, const char **argv)
|
|||
kwork.report = KWORK_REPORT_RUNTIME;
|
||||
setup_sorting(&kwork, report_options, report_usage);
|
||||
setup_event_list(&kwork, kwork_options, kwork_usage);
|
||||
return perf_kwork__report(&kwork);
|
||||
ret = perf_kwork__report(&kwork);
|
||||
} else if (strlen(argv[0]) > 2 && strstarts("latency", argv[0])) {
|
||||
kwork.sort_order = default_latency_sort_order;
|
||||
if (argc > 1) {
|
||||
|
|
@ -2485,7 +2497,7 @@ int cmd_kwork(int argc, const char **argv)
|
|||
kwork.report = KWORK_REPORT_LATENCY;
|
||||
setup_sorting(&kwork, latency_options, latency_usage);
|
||||
setup_event_list(&kwork, kwork_options, kwork_usage);
|
||||
return perf_kwork__report(&kwork);
|
||||
ret = perf_kwork__report(&kwork);
|
||||
} else if (strlen(argv[0]) > 2 && strstarts("timehist", argv[0])) {
|
||||
if (argc > 1) {
|
||||
argc = parse_options(argc, argv, timehist_options, timehist_usage, 0);
|
||||
|
|
@ -2494,7 +2506,7 @@ int cmd_kwork(int argc, const char **argv)
|
|||
}
|
||||
kwork.report = KWORK_REPORT_TIMEHIST;
|
||||
setup_event_list(&kwork, kwork_options, kwork_usage);
|
||||
return perf_kwork__timehist(&kwork);
|
||||
ret = perf_kwork__timehist(&kwork);
|
||||
} else if (strlen(argv[0]) > 2 && strstarts("top", argv[0])) {
|
||||
kwork.sort_order = default_top_sort_order;
|
||||
if (argc > 1) {
|
||||
|
|
@ -2507,12 +2519,12 @@ int cmd_kwork(int argc, const char **argv)
|
|||
kwork.event_list_str = "sched, irq, softirq";
|
||||
setup_event_list(&kwork, kwork_options, kwork_usage);
|
||||
setup_sorting(&kwork, top_options, top_usage);
|
||||
return perf_kwork__top(&kwork);
|
||||
ret = perf_kwork__top(&kwork);
|
||||
} else
|
||||
usage_with_options(kwork_usage, kwork_options);
|
||||
|
||||
/* free usage string allocated by parse_options_subcommand */
|
||||
free((void *)kwork_usage[0]);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user