[PATCH v3 3/3] perf tools: Fix memory leak in cmd_kvm()
Michalis Niarchos <[email protected]> Mon, 03 Aug 2026 15:51:54 +0200
| Newsgroups | org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.linux-perf-users |
|---|---|
| Message-ID | <[email protected]> |
The usage string is allocated by parse_options_subcommand() and freed only on one return path. Using a single return point guarantees it is freed on all occasions. Signed-off-by: Michalis Niarchos <[email protected]> --- tools/perf/builtin-kvm.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 8e14d037d7d9..04cf9bd5b595 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -2132,6 +2132,7 @@ int cmd_kvm(int argc, const char **argv) const char *const kvm_subcommands[] = { "top", "record", "report", "diff", "buildid-list", "stat", NULL }; const char *kvm_usage[] = { NULL, NULL }; + int ret = 0; exclude_GH_default = true; perf_host = 0; @@ -2148,25 +2149,34 @@ int cmd_kvm(int argc, const char **argv) if (!file_name) file_name = get_filename_for_perf_kvm(); - if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) - return __cmd_record(file_name, argc, argv); - else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) - return __cmd_report(file_name, argc, argv); - else if (strlen(argv[0]) > 2 && strstarts("diff", argv[0])) - return cmd_diff(argc, argv); - else if (!strcmp(argv[0], "top")) - return __cmd_top(argc, argv); - else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) - return __cmd_buildid_list(file_name, argc, argv); + if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) { + ret = __cmd_record(file_name, argc, argv); + goto exit; + } else if (strlen(argv[0]) > 2 && strstarts("report", argv[0])) { + ret = __cmd_report(file_name, argc, argv); + goto exit; + } else if (strlen(argv[0]) > 2 && strstarts("diff", argv[0])) { + ret = cmd_diff(argc, argv); + goto exit; + } else if (!strcmp(argv[0], "top")) { + ret = __cmd_top(argc, argv); + goto exit; + } else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) { + ret = __cmd_buildid_list(file_name, argc, argv); + goto exit; + } #if defined(HAVE_LIBTRACEEVENT) - else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) - return kvm_cmd_stat(file_name, argc, argv); + else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) { + ret = kvm_cmd_stat(file_name, argc, argv); + goto exit; + } #endif else usage_with_options(kvm_usage, kvm_options); +exit: /* free usage string allocated by parse_options_subcommand */ free((void *)kvm_usage[0]); - return 0; + return ret; } -- 2.55.0