[PATCH 7/8] perf machine: Free scandir entries in guest kernel map creation

From: Arnaldo Carvalho de Melo

Date: Sun Jul 26 2026 - 19:45:08 EST


From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>

machines__create_guest_kernel_maps() calls scandir() which allocates
both the namelist array and each individual dirent entry. The code
frees the namelist array but not the individual entries, leaking memory
proportional to the number of directories under guestmount.

Free each namelist[i] after it is no longer needed.

Fixes: a1645ce12adb ("perf: 'perf kvm' tool for monitoring guest performance from host")
Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
Cc: Zhang, Yanmin <yanmin_zhang@xxxxxxxxxxxxxxx>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/util/machine.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 1700130adedb3a89..48c4b963e8097f4a 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1256,6 +1256,7 @@ int machines__create_guest_kernel_maps(struct machines *machines)
for (i = 0; i < items; i++) {
if (!isdigit(namelist[i]->d_name[0])) {
/* Filter out . and .. */
+ free(namelist[i]);
continue;
}
errno = 0;
@@ -1265,6 +1266,7 @@ int machines__create_guest_kernel_maps(struct machines *machines)
(errno == ERANGE)) {
pr_debug("invalid directory (%s). Skipping.\n",
namelist[i]->d_name);
+ free(namelist[i]);
continue;
}
snprintf(path, sizeof(path), "%s/%s/proc/kallsyms",
@@ -1272,9 +1274,11 @@ int machines__create_guest_kernel_maps(struct machines *machines)
namelist[i]->d_name);
if (access(path, R_OK)) {
pr_debug("Can't access file %s\n", path);
+ free(namelist[i]);
continue;
}
machines__create_kernel_maps(machines, pid);
+ free(namelist[i]);
}
free(namelist);
}
--
2.55.0