[PATCH 4/4] perf tools: Fix memory leak in cmd_kvm()
Michalis Niarchos <[email protected]> Mon, 03 Aug 2026 12:33:23 +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 | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 189ef3576e34..56062c305db1 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -2145,6 +2145,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; @@ -2163,29 +2164,39 @@ int cmd_kvm(int argc, const char **argv) if (!file_name) { pr_err("Failed to allocate memory for filename\n"); - return -ENOMEM; + ret = -ENOMEM; + goto exit; } } - 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