]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
riscv: Fix memory leak in module_frob_arch_sections()
authorMiaoqian Lin <linmq006@gmail.com>
Mon, 27 Oct 2025 17:40:44 +0000 (11:40 -0600)
committerPaul Walmsley <pjw@kernel.org>
Mon, 27 Oct 2025 17:40:44 +0000 (11:40 -0600)
The current code directly overwrites the scratch pointer with the
return value of kvrealloc(). If kvrealloc() fails and returns NULL,
the original buffer becomes unreachable, causing a memory leak.

Fix this by using a temporary variable to store kvrealloc()'s return
value and only update the scratch pointer on success.

Found via static anlaysis and this is similar to commit 42378a9ca553
("bpf, verifier: Fix memory leak in array reallocation for stack state")

Fixes: be17c0df6795 ("riscv: module: Optimize PLT/GOT entry counting")
Cc: stable@vger.kernel.org
Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
Link: https://lore.kernel.org/r/20251026091912.39727-1-linmq006@gmail.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
arch/riscv/kernel/module-sections.c

index 75551ac6504c5da36fb7adb7f4bd2192fe5438ba..1675cbad8619d1c50cb48ff9a9a4c79721e6a066 100644 (file)
@@ -119,6 +119,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
        unsigned int num_plts = 0;
        unsigned int num_gots = 0;
        Elf_Rela *scratch = NULL;
+       Elf_Rela *new_scratch;
        size_t scratch_size = 0;
        int i;
 
@@ -168,9 +169,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
                scratch_size_needed = (num_scratch_relas + num_relas) * sizeof(*scratch);
                if (scratch_size_needed > scratch_size) {
                        scratch_size = scratch_size_needed;
-                       scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL);
-                       if (!scratch)
+                       new_scratch = kvrealloc(scratch, scratch_size, GFP_KERNEL);
+                       if (!new_scratch) {
+                               kvfree(scratch);
                                return -ENOMEM;
+                       }
+                       scratch = new_scratch;
                }
 
                for (size_t j = 0; j < num_relas; j++)