Commit c42458fc authored by Miaoqian Lin's avatar Miaoqian Lin Committed by Paul Walmsley
Browse files

riscv: Fix memory leak in module_frob_arch_sections()



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 42378a9c
("bpf, verifier: Fix memory leak in array reallocation for stack state")

Fixes: be17c0df ("riscv: module: Optimize PLT/GOT entry counting")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarMiaoqian Lin <linmq006@gmail.com>
Link: https://lore.kernel.org/r/20251026091912.39727-1-linmq006@gmail.com


Signed-off-by: default avatarPaul Walmsley <pjw@kernel.org>
parent a74f038f
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -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,10 +169,13 @@ 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++)
			if (rela_needs_plt_got_entry(&relas[j]))