From 6703ab347f4b7c228bbe391dafbe57b1a62b2997 Mon Sep 17 00:00:00 2001 From: "Jose Fernandez (Anthropic)" Date: Thu, 24 Sep 2026 22:35:45 +0000 Subject: [PATCH] ftrace: Do not leak a module's empty page group When every mcount_loc entry of a module is skipped, ftrace_process_locs() leaves the module's first page group linked with no records. ftrace_release_mod() matches a module's groups by records[0].ip, which is 0 here, so the group is never freed. While it stays linked, ftrace_free_mem() reads pg->records[pg->index - 1] with pg->index == 0 on every later module load, as lookup_rec() did before commit ee92fa443358f ("ftrace: Fix invalid address access in lookup_rec() when index is 0"). Unlink and free the new page groups when none of them got a record. Link: https://patch.msgid.link/20260924-b4-arm64-callops-kcfi-v2-1-587865b6d991@linux.dev Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/all/20260904013350.5141B1F000E9@smtp.kernel.org/ Assisted-by: LLM Signed-off-by: Jose Fernandez (Anthropic) Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 98535f5533db..c8f8dd1cb92f 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -7720,6 +7720,20 @@ static int ftrace_process_locs(struct module *mod, rec->ip = addr; } + /* + * ftrace_release_mod() finds a module's page groups by their first + * record. If every entry was skipped there is none, so unlink the + * new page groups and free them now. + */ + if (mod && !start_pg->index) { + ftrace_pages->next = NULL; + mutex_unlock(&ftrace_lock); + /* Need to synchronize with ftrace_location_range() */ + synchronize_rcu(); + ftrace_free_pages(start_pg); + return 0; + } + if (pg->next) { pg_unuse = pg->next; pg->next = NULL;