perf tools kvm: Add missed memory allocation check and free

Current code allocates rec_argv[] array, but doesn't check if the
allocation is successful and explicitly free the rec_argv[] array.

Add them back.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Dapeng Mi 2025-09-19 10:16:54 +08:00 committed by Arnaldo Carvalho de Melo
parent f0015d8149
commit 9262fa242b

View file

@ -1638,9 +1638,11 @@ exit:
#define STRDUP_FAIL_EXIT(s) \
({ char *_p; \
_p = strdup(s); \
if (!_p) \
return -ENOMEM; \
_p = strdup(s); \
if (!_p) { \
ret = -ENOMEM; \
goto EXIT; \
} \
_p; \
})
@ -1688,7 +1690,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
for (j = 0; j < events_tp_size; j++) {
rec_argv[i++] = "-e";
rec_argv[i++] = STRDUP_FAIL_EXIT("-e");
rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp[j]);
}
@ -1696,7 +1698,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
for (j = 1; j < (unsigned int)argc; j++, i++)
rec_argv[i] = argv[j];
rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN);
set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN);
@ -1719,7 +1721,13 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
set_option_flag(record_options, 0, "transaction", PARSE_OPT_DISABLED);
record_usage = kvm_stat_record_usage;
return cmd_record(i, rec_argv);
ret = cmd_record(i, rec_argv);
EXIT:
for (i = 0; i < rec_argc; i++)
free((void *)rec_argv[i]);
free(rec_argv);
return ret;
}
static int
@ -2006,52 +2014,79 @@ static int __cmd_record(const char *file_name, int argc, const char **argv)
rec_argc = argc + 2;
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("record");
rec_argv[i++] = strdup("-o");
rec_argv[i++] = strdup(file_name);
if (!rec_argv)
return -ENOMEM;
rec_argv[i++] = STRDUP_FAIL_EXIT("record");
rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
rec_argv[i++] = STRDUP_FAIL_EXIT(file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
BUG_ON(i != rec_argc);
return cmd_record(i, rec_argv);
ret = cmd_record(i, rec_argv);
EXIT:
for (i = 0; i < rec_argc; i++)
free((void *)rec_argv[i]);
free(rec_argv);
return ret;
}
static int __cmd_report(const char *file_name, int argc, const char **argv)
{
int rec_argc, i = 0, j;
int rec_argc, i = 0, j, ret;
const char **rec_argv;
rec_argc = argc + 2;
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("report");
rec_argv[i++] = strdup("-i");
rec_argv[i++] = strdup(file_name);
if (!rec_argv)
return -ENOMEM;
rec_argv[i++] = STRDUP_FAIL_EXIT("report");
rec_argv[i++] = STRDUP_FAIL_EXIT("-i");
rec_argv[i++] = STRDUP_FAIL_EXIT(file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
BUG_ON(i != rec_argc);
return cmd_report(i, rec_argv);
ret = cmd_report(i, rec_argv);
EXIT:
for (i = 0; i < rec_argc; i++)
free((void *)rec_argv[i]);
free(rec_argv);
return ret;
}
static int
__cmd_buildid_list(const char *file_name, int argc, const char **argv)
{
int rec_argc, i = 0, j;
int rec_argc, i = 0, j, ret;
const char **rec_argv;
rec_argc = argc + 2;
rec_argv = calloc(rec_argc + 1, sizeof(char *));
rec_argv[i++] = strdup("buildid-list");
rec_argv[i++] = strdup("-i");
rec_argv[i++] = strdup(file_name);
if (!rec_argv)
return -ENOMEM;
rec_argv[i++] = STRDUP_FAIL_EXIT("buildid-list");
rec_argv[i++] = STRDUP_FAIL_EXIT("-i");
rec_argv[i++] = STRDUP_FAIL_EXIT(file_name);
for (j = 1; j < argc; j++, i++)
rec_argv[i] = argv[j];
rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
BUG_ON(i != rec_argc);
return cmd_buildid_list(i, rec_argv);
ret = cmd_buildid_list(i, rec_argv);
EXIT:
for (i = 0; i < rec_argc; i++)
free((void *)rec_argv[i]);
free(rec_argv);
return ret;
}
int cmd_kvm(int argc, const char **argv)