[PATCH] trace-cmd library: Fix virtual memory leak in tracecmd_close()

Zhengchuan Liang <[email protected]> Mon, 13 Apr 2026 00:58:46 -0700
Newsgroups org.kernel.vger.linux-trace-devel
Message-ID <[email protected]>
tracecmd_close() only released the current cpu page and then freed the
remaining page_map objects without unmapping them. As a result, cached
pages and their mmap()ed ranges could survive handle teardown and leak
virtual memory.

Release all cached cpu_data->pages[] entries with __free_page() and
munmap any remaining page_map mappings before freeing them.

Reported-by: Zhao Zhang <[email protected]>
Co-developed-by: Zhao Zhang <[email protected]>
Signed-off-by: Zhao Zhang <[email protected]>
Signed-off-by: Zhengchuan Liang <[email protected]>
---
 lib/trace-cmd/trace-input.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index 0fa9d956..8e30a8d3 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -5237,9 +5237,15 @@ void tracecmd_close(struct tracecmd_input *handle)
 	for (cpu = 0; cpu < handle->cpus; cpu++) {
 		/* The tracecmd_peek_data may have cached a record */
 		free_next(handle, cpu);
-		free_page(handle, cpu);
 		if (handle->cpu_data) {
 			cpu_data = &handle->cpu_data[cpu];
+			if (cpu_data->pages) {
+				for (i = 0; i < cpu_data->nr_pages; i++) {
+					if (cpu_data->pages[i])
+						__free_page(handle, cpu_data->pages[i]);
+				}
+			}
+			cpu_data->page = NULL;
 			if (cpu_data->kbuf) {
 				kbuffer_free(cpu_data->kbuf);
 				if (cpu_data->page_map)
@@ -5265,6 +5271,7 @@ void tracecmd_close(struct tracecmd_input *handle)
 			}
 			free(cpu_data->compress.chunks);
 			list_for_each_entry_safe(page_map, n, &cpu_data->page_maps, list) {
+				munmap(page_map->map, page_map->size);
 				list_del(&page_map->list);
 				free(page_map);
 			}
-- 
2.34.1