Linux Perf Users
 help / color / mirror / Atom feed
* [PATCH v2 0/4] perf tools: Fix memory issues
@ 2026-08-03 13:05 Michalis Niarchos via B4 Relay
  2026-08-03 13:05 ` [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Michalis Niarchos via B4 Relay @ 2026-08-03 13:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark
  Cc: linux-perf-users, linux-kernel, Michalis Niarchos

Running:
  $ perf kvm stat record -a sleep 10

gives this output:
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 1.361 MB perf.data.guest ]
  double free or corruption (!prev)

In the process of resolving this, I came across some memory leaks.

Signed-off-by: Michalis Niarchos <michael.niarchos@gmail.com>
---
Changes in v2:
- Removed code block that was rendered dead by the
  get_filename_for_perf_kvm() change.
- Dropped invalid free() fix from kvm_events_report().
- Added double free fixes for: __cmd_record(), __cmd_report(),
  __cmd_buildid_list(), and __cmd_top(), which follow the same pattern
  as kvm_events_record().
- Link to v1: https://patch.msgid.link/20260803-perf-kvm-fixes-v1-0-a5db849ac973@gmail.com

To: Peter Zijlstra <peterz@infradead.org>
To: Ingo Molnar <mingo@redhat.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Namhyung Kim <namhyung@kernel.org>
To: Mark Rutland <mark.rutland@arm.com>
To: Alexander Shishkin <alexander.shishkin@linux.intel.com>
To: Jiri Olsa <jolsa@kernel.org>
To: Ian Rogers <irogers@google.com>
To: Adrian Hunter <adrian.hunter@intel.com>
To: James Clark <james.clark@linaro.org>
Cc: linux-perf-users@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Michalis Niarchos (4):
      perf tools: Fix memory leak in cmd_kvm()
      perf tools: Fix double free and memory leak in kvm_events_record()
      perf tools: Fix memory leak in cmd_kvm()
      perf tools: Fix double frees and memory leaks in cmd_kvm()

 tools/perf/builtin-kvm.c                         | 99 +++++++++++-------------
 tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c |  4 +-
 tools/perf/util/kvm-stat-arch/kvm-stat-x86.c     | 10 +--
 3 files changed, 50 insertions(+), 63 deletions(-)
---
base-commit: a1ed064cb4db70af8c4177b3805ca5b8b0be567e
change-id: 20260731-perf-kvm-fixes-a17f0aa048ad

Best regards,
--  
Michalis Niarchos <michael.niarchos@gmail.com>



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm()
  2026-08-03 13:05 [PATCH v2 0/4] perf tools: Fix memory issues Michalis Niarchos via B4 Relay
@ 2026-08-03 13:05 ` Michalis Niarchos via B4 Relay
  2026-08-03 13:19   ` sashiko-bot
  2026-08-03 13:05 ` [PATCH v2 2/4] perf tools: Fix double free and memory leak in kvm_events_record() Michalis Niarchos via B4 Relay
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Michalis Niarchos via B4 Relay @ 2026-08-03 13:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark
  Cc: linux-perf-users, linux-kernel, Michalis Niarchos

From: Michalis Niarchos <michael.niarchos@gmail.com>

filename may get allocated by get_filename_for_perf_kvm(), but is
never freed. Use string literals to remove the need for freeing.

Signed-off-by: Michalis Niarchos <michael.niarchos@gmail.com>
---
 tools/perf/builtin-kvm.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 394302ebdb16..44c6998f2ee5 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -606,11 +606,11 @@ static const char *get_filename_for_perf_kvm(void)
 	const char *filename;
 
 	if (perf_host && !perf_guest)
-		filename = strdup("perf.data.host");
+		filename = "perf.data.host";
 	else if (!perf_host && perf_guest)
-		filename = strdup("perf.data.guest");
+		filename = "perf.data.guest";
 	else
-		filename = strdup("perf.data.kvm");
+		filename = "perf.data.kvm";
 
 	return filename;
 }

-- 
2.55.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/4] perf tools: Fix double free and memory leak in kvm_events_record()
  2026-08-03 13:05 [PATCH v2 0/4] perf tools: Fix memory issues Michalis Niarchos via B4 Relay
  2026-08-03 13:05 ` [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
@ 2026-08-03 13:05 ` Michalis Niarchos via B4 Relay
  2026-08-03 13:37   ` sashiko-bot
  2026-08-03 13:05 ` [PATCH v2 3/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
  2026-08-03 13:05 ` [PATCH v2 4/4] perf tools: Fix double frees and memory leaks " Michalis Niarchos via B4 Relay
  3 siblings, 1 reply; 8+ messages in thread
From: Michalis Niarchos via B4 Relay @ 2026-08-03 13:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark
  Cc: linux-perf-users, linux-kernel, Michalis Niarchos

From: Michalis Niarchos <michael.niarchos@gmail.com>

cmd_record() reorders the contents of the rec_argv pointer array, so
its entry order no longer matches the order in which the caller
originally allocated them. Freeing the contents of rec_argv by
iterating the reordered array results in some pointers being freed
twice and others never freed.

All the entries of rec_argv come from literals or pointers that are
valid for the lifetime of this call. Reference them directly instead
of duplicating to remove the need to individually track and free each
entry.

Signed-off-by: Michalis Niarchos <michael.niarchos@gmail.com>
---
 tools/perf/builtin-kvm.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 44c6998f2ee5..45c92ab74fdd 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1681,18 +1681,18 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 		return -ENOMEM;
 
 	for (i = 0; i < ARRAY_SIZE(record_args); i++)
-		rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
+		rec_argv[i] = record_args[i];
 
 	for (j = 0; j < events_tp_size; j++) {
-		rec_argv[i++] = STRDUP_FAIL_EXIT("-e");
-		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp(e_machine)[j]);
+		rec_argv[i++] = "-e";
+		rec_argv[i++] = kvm_events_tp(e_machine)[j];
 	}
 
-	rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
-	rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
+	rec_argv[i++] = "-o";
+	rec_argv[i++] = kvm->file_name;
 
 	for (j = 1; j < (unsigned int)argc; j++, i++)
-		rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
+		rec_argv[i] = argv[j];
 
 	set_option_flag(record_options, 'e', "event", PARSE_OPT_HIDDEN);
 	set_option_flag(record_options, 0, "filter", PARSE_OPT_HIDDEN);
@@ -1717,9 +1717,6 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 	record_usage = kvm_stat_record_usage;
 	ret = cmd_record(i, rec_argv);
 
-EXIT:
-	for (i = 0; i < rec_argc; i++)
-		free((void *)rec_argv[i]);
 	free(rec_argv);
 	return ret;
 }

-- 
2.55.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/4] perf tools: Fix memory leak in cmd_kvm()
  2026-08-03 13:05 [PATCH v2 0/4] perf tools: Fix memory issues Michalis Niarchos via B4 Relay
  2026-08-03 13:05 ` [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
  2026-08-03 13:05 ` [PATCH v2 2/4] perf tools: Fix double free and memory leak in kvm_events_record() Michalis Niarchos via B4 Relay
@ 2026-08-03 13:05 ` Michalis Niarchos via B4 Relay
  2026-08-03 13:05 ` [PATCH v2 4/4] perf tools: Fix double frees and memory leaks " Michalis Niarchos via B4 Relay
  3 siblings, 0 replies; 8+ messages in thread
From: Michalis Niarchos via B4 Relay @ 2026-08-03 13:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark
  Cc: linux-perf-users, linux-kernel, Michalis Niarchos

From: Michalis Niarchos <michael.niarchos@gmail.com>

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 <michael.niarchos@gmail.com>
---
 tools/perf/builtin-kvm.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 45c92ab74fdd..9504c83e2074 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -2142,6 +2142,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;
@@ -2155,34 +2156,37 @@ int cmd_kvm(int argc, const char **argv)
 	if (!perf_host)
 		perf_guest = 1;
 
-	if (!file_name) {
+	if (!file_name)
 		file_name = get_filename_for_perf_kvm();
 
-		if (!file_name) {
-			pr_err("Failed to allocate memory for filename\n");
-			return -ENOMEM;
-		}
+	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 (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 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



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/4] perf tools: Fix double frees and memory leaks in cmd_kvm()
  2026-08-03 13:05 [PATCH v2 0/4] perf tools: Fix memory issues Michalis Niarchos via B4 Relay
                   ` (2 preceding siblings ...)
  2026-08-03 13:05 ` [PATCH v2 3/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
@ 2026-08-03 13:05 ` Michalis Niarchos via B4 Relay
  2026-08-03 13:39   ` sashiko-bot
  3 siblings, 1 reply; 8+ messages in thread
From: Michalis Niarchos via B4 Relay @ 2026-08-03 13:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
	Ian Rogers, Adrian Hunter, James Clark
  Cc: linux-perf-users, linux-kernel, Michalis Niarchos

From: Michalis Niarchos <michael.niarchos@gmail.com>

The involved functions follow the same pattern as kvm_events_record().

Signed-off-by: Michalis Niarchos <michael.niarchos@gmail.com>
---
 tools/perf/builtin-kvm.c                         | 36 +++++++++---------------
 tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c |  4 +--
 tools/perf/util/kvm-stat-arch/kvm-stat-x86.c     | 10 ++-----
 3 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 9504c83e2074..04cf9bd5b595 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -2003,11 +2003,11 @@ static int __cmd_record(const char *file_name, int argc, const char **argv)
 	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);
+	rec_argv[i++] = "record";
+	rec_argv[i++] = "-o";
+	rec_argv[i++] = file_name;
 	for (j = 1; j < argc; j++, i++)
-		rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
+		rec_argv[i] = argv[j];
 
 	BUG_ON(i + 2 != rec_argc);
 
@@ -2018,8 +2018,6 @@ static int __cmd_record(const char *file_name, int argc, const char **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;
 }
@@ -2034,19 +2032,16 @@ static int __cmd_report(const char *file_name, int argc, const char **argv)
 	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);
+	rec_argv[i++] = "report";
+	rec_argv[i++] = "-i";
+	rec_argv[i++] = file_name;
 	for (j = 1; j < argc; j++, i++)
-		rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
+		rec_argv[i] = argv[j];
 
 	BUG_ON(i != rec_argc);
 
 	ret = cmd_report(i, rec_argv);
 
-EXIT:
-	for (i = 0; i < rec_argc; i++)
-		free((void *)rec_argv[i]);
 	free(rec_argv);
 	return ret;
 }
@@ -2062,19 +2057,16 @@ __cmd_buildid_list(const char *file_name, int argc, const char **argv)
 	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);
+	rec_argv[i++] = "buildid-list";
+	rec_argv[i++] = "-i";
+	rec_argv[i++] = file_name;
 	for (j = 1; j < argc; j++, i++)
-		rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]);
+		rec_argv[i] = argv[j];
 
 	BUG_ON(i != rec_argc);
 
 	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;
 }
@@ -2094,7 +2086,7 @@ static int __cmd_top(int argc, const char **argv)
 		return -ENOMEM;
 
 	for (i = 0; i < argc; i++)
-		rec_argv[i] = STRDUP_FAIL_EXIT(argv[i]);
+		rec_argv[i] = argv[i];
 
 	BUG_ON(i != argc);
 
@@ -2105,8 +2097,6 @@ static int __cmd_top(int argc, const char **argv)
 	ret = cmd_top(i, rec_argv);
 
 EXIT:
-	for (i = 0; i < rec_argc; i++)
-		free((void *)rec_argv[i]);
 	free(rec_argv);
 	return ret;
 }
diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c b/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c
index 96d9c4ae0209..37f36c6bf895 100644
--- a/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c
@@ -196,8 +196,8 @@ int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv)
 	parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
 	if (!event) {
 		if (perf_pmus__have_event("trace_imc", "trace_cycles")) {
-			argv[j++] = strdup("-e");
-			argv[j++] = strdup("trace_imc/trace_cycles/");
+			argv[j++] = "-e";
+			argv[j++] = "trace_imc/trace_cycles/";
 			*argc += 2;
 		} else {
 			free(tmp);
diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c b/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c
index 788d216f0852..67babdd3daf1 100644
--- a/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c
@@ -213,7 +213,7 @@ int __kvm_add_default_arch_event_x86(int *argc, const char **argv)
 {
 	const char **tmp;
 	bool event = false;
-	int ret = 0, i, j = *argc;
+	int i, j = *argc;
 
 	const struct option event_options[] = {
 		OPT_BOOLEAN('e', "event", &event, NULL),
@@ -233,17 +233,13 @@ int __kvm_add_default_arch_event_x86(int *argc, const char **argv)
 
 	parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
 	if (!event) {
-		argv[j++] = STRDUP_FAIL_EXIT("-e");
-		argv[j++] = STRDUP_FAIL_EXIT("cycles");
+		argv[j++] = "-e";
+		argv[j++] = "cycles";
 		*argc += 2;
 	}
 
 	free(tmp);
 	return 0;
-
-EXIT:
-	free(tmp);
-	return ret;
 }
 
 const char * const *__kvm_events_tp_x86(void)

-- 
2.55.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm()
  2026-08-03 13:05 ` [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
@ 2026-08-03 13:19   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-03 13:19 UTC (permalink / raw)
  To: Michalis Niarchos; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Obsolete dead code and misleading error message left behind after switching to string literals.
--

--- Patch [1]: [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm() ---
commit 86f226d29d0e3321d6c203d041f55a455eb36daf
Author: Michalis Niarchos <michael.niarchos@gmail.com>

perf tools: Fix memory leak in cmd_kvm()

filename may get allocated by get_filename_for_perf_kvm(), but is
never freed. Use string literals to remove the need for freeing.

> diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
> index 394302ebdb161..44c6998f2ee5d 100644
> --- a/tools/perf/builtin-kvm.c
> +++ b/tools/perf/builtin-kvm.c
> @@ -606,11 +606,11 @@ static const char *get_filename_for_perf_kvm(void)
>  	const char *filename;
>  
>  	if (perf_host && !perf_guest)
> -		filename = strdup("perf.data.host");
> +		filename = "perf.data.host";
>  	else if (!perf_host && perf_guest)
> -		filename = strdup("perf.data.guest");
> +		filename = "perf.data.guest";
>  	else
> -		filename = strdup("perf.data.kvm");
> +		filename = "perf.data.kvm";
>  
>  	return filename;
>  }

[Severity: Low]
Since this function now returns string literals, it can never return NULL.

Should we also remove the unreachable error handling in cmd_kvm() where
get_filename_for_perf_kvm() is called?

tools/perf/builtin-kvm.c:cmd_kvm() {
    ...
	if (!file_name) {
		file_name = get_filename_for_perf_kvm();

		if (!file_name) {
			pr_err("Failed to allocate memory for filename\n");
			return -ENOMEM;
		}
	}
    ...
}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260803-perf-kvm-fixes-v2-0-1b337189fffc@gmail.com?part=1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/4] perf tools: Fix double free and memory leak in kvm_events_record()
  2026-08-03 13:05 ` [PATCH v2 2/4] perf tools: Fix double free and memory leak in kvm_events_record() Michalis Niarchos via B4 Relay
@ 2026-08-03 13:37   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-03 13:37 UTC (permalink / raw)
  To: Michalis Niarchos; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Medium] The patch addresses an array-mutation bug in `kvm_events_record()` but leaves identical instances of the bug unfixed in `__cmd_record()`, `__cmd_report()`, `__cmd_buildid_list()`, and `__cmd_top()`.
--

--- Patch [2]: [PATCH v2 2/4] perf tools: Fix double free and memory leak in kvm_events_record() ---
commit de06a9553df4c03dc3591b78a5d37cfb9f36b1e0
Author: Michalis Niarchos <michael.niarchos@gmail.com>

perf tools: Fix double free and memory leak in kvm_events_record()

cmd_record() reorders the contents of the rec_argv pointer array, causing
an issue where pointers are freed twice and others never freed. This patch
fixes the double free and memory leak by referencing literals directly
instead of duplicating them, removing the need to track and free each entry.

> diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
> index 44c6998f2ee5d..45c92ab74fdd6 100644
> --- a/tools/perf/builtin-kvm.c
> +++ b/tools/perf/builtin-kvm.c

[ ... ]

> @@ -1717,9 +1717,6 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
>  	record_usage = kvm_stat_record_usage;
>  	ret = cmd_record(i, rec_argv);
>  
> -EXIT:
> -	for (i = 0; i < rec_argc; i++)
> -		free((void *)rec_argv[i]);

[Severity: Medium]
This is a pre-existing issue, but does this exact same array-mutation bug still
exist in other functions within this file?

It looks like __cmd_record(), __cmd_report(), __cmd_buildid_list(), and
__cmd_top() all have this identical cleanup loop:

	for (i = 0; i < rec_argc; i++)
		free((void *)rec_argv[i]);

Since these functions also pass the allocated rec_argv array to command handlers
that use parse_options() (which consumes options in-place and shifts non-option
arguments forward), do these other commands also suffer from a double-free
and memory leak?

>  	free(rec_argv);
>  	return ret;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260803-perf-kvm-fixes-v2-0-1b337189fffc@gmail.com?part=2

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 4/4] perf tools: Fix double frees and memory leaks in cmd_kvm()
  2026-08-03 13:05 ` [PATCH v2 4/4] perf tools: Fix double frees and memory leaks " Michalis Niarchos via B4 Relay
@ 2026-08-03 13:39   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-03 13:39 UTC (permalink / raw)
  To: Michalis Niarchos; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The patch fixes memory leaks and double-free vulnerabilities in `__cmd_record`, `__cmd_report`, `__cmd_buildid_list`, and `__cmd_top` by removing `STRDUP_FAIL_EXIT` and the element-wise `free()` loop on `rec_argv`, but it misses applying the exact same fix to `kvm_events_record()` which suffers from the identical bug.
--

--- Patch [4]: [PATCH v2 4/4] perf tools: Fix double frees and memory leaks in cmd_kvm() ---
commit 0b9d8e748caa2edae90fe11689ed1a0bf618e63b
Author: Michalis Niarchos <michael.niarchos@gmail.com>

perf tools: Fix double frees and memory leaks in cmd_kvm()

This commit fixes double free and memory leak vulnerabilities in various
builtin KVM commands (like __cmd_record, __cmd_report, __cmd_buildid_list,
and __cmd_top). It achieves this by removing the use of STRDUP_FAIL_EXIT and
dropping the element-wise free loop on rec_argv.

> diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
> index 9504c83e20744..04cf9bd5b5959 100644
> --- a/tools/perf/builtin-kvm.c
> +++ b/tools/perf/builtin-kvm.c
> @@ -2018,8 +2018,6 @@ static int __cmd_record(const char *file_name, int argc, const char **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;
>  }

[Severity: High]
This is a pre-existing issue and was not introduced by this patch, but does
kvm_events_record() in tools/perf/builtin-kvm.c require this exact same fix?

The commit message notes that the fixed functions follow the same pattern
as kvm_events_record(). However, looking at kvm_events_record(), it appears
it still contains the flawed cleanup loop:

tools/perf/builtin-kvm.c:kvm_events_record() {
    ...
EXIT:
    for (i = 0; i < rec_argc; i++)
        free((void *)rec_argv[i]);
    free(rec_argv);
    return ret;
}

When a user runs 'perf kvm stat record', cmd_record() processes the arguments
by calling parse_options(). Since parse_options() shifts the array in-place
using memmove() to consume recognized arguments, iterating over the original
length of rec_argv (rec_argc) during cleanup encounters duplicated pointers at
the end of the array.

Will leaving this loop in kvm_events_record() lead to a double-free memory
corruption when those duplicate pointers are freed?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260803-perf-kvm-fixes-v2-0-1b337189fffc@gmail.com?part=4

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-08-03 13:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03 13:05 [PATCH v2 0/4] perf tools: Fix memory issues Michalis Niarchos via B4 Relay
2026-08-03 13:05 ` [PATCH v2 1/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
2026-08-03 13:19   ` sashiko-bot
2026-08-03 13:05 ` [PATCH v2 2/4] perf tools: Fix double free and memory leak in kvm_events_record() Michalis Niarchos via B4 Relay
2026-08-03 13:37   ` sashiko-bot
2026-08-03 13:05 ` [PATCH v2 3/4] perf tools: Fix memory leak in cmd_kvm() Michalis Niarchos via B4 Relay
2026-08-03 13:05 ` [PATCH v2 4/4] perf tools: Fix double frees and memory leaks " Michalis Niarchos via B4 Relay
2026-08-03 13:39   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox