Skip to content

Commit 96df59b

Browse files
Li Huafeipalmer-dabbelt
authored andcommitted
RISC-V: kexec: Fix memory leak of fdt buffer
This is reported by kmemleak detector: unreferenced object 0xff60000082864000 (size 9588): comm "kexec", pid 146, jiffies 4294900634 (age 64.788s) hex dump (first 32 bytes): d0 0d fe ed 00 00 12 ed 00 00 00 48 00 00 11 40 ...........H...@ 00 00 00 28 00 00 00 11 00 00 00 02 00 00 00 00 ...(............ backtrace: [<00000000f95b17c4>] kmemleak_alloc+0x34/0x3e [<00000000b9ec8e3e>] kmalloc_order+0x9c/0xc4 [<00000000a95cf02e>] kmalloc_order_trace+0x34/0xb6 [<00000000f01e68b4>] __kmalloc+0x5c2/0x62a [<000000002bd497b2>] kvmalloc_node+0x66/0xd6 [<00000000906542fa>] of_kexec_alloc_and_setup_fdt+0xa6/0x6ea [<00000000e1166bde>] elf_kexec_load+0x206/0x4ec [<0000000036548e09>] kexec_image_load_default+0x40/0x4c [<0000000079fbe1b4>] sys_kexec_file_load+0x1c4/0x322 [<0000000040c62c03>] ret_from_syscall+0x0/0x2 In elf_kexec_load(), a buffer is allocated via kvmalloc() to store fdt. While it's not freed back to system when kexec kernel is reloaded or unloaded. Then memory leak is caused. Fix it by introducing riscv specific function arch_kimage_file_post_load_cleanup(), and freeing the buffer there. Fixes: 6261586 ("RISC-V: Add kexec_file support") Signed-off-by: Li Huafei <[email protected]> Reviewed-by: Conor Dooley <[email protected]> Reviewed-by: Liao Chang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: [email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 9704bea commit 96df59b

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

arch/riscv/include/asm/kexec.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ crash_setup_regs(struct pt_regs *newregs,
3939
#define ARCH_HAS_KIMAGE_ARCH
4040

4141
struct kimage_arch {
42+
void *fdt; /* For CONFIG_KEXEC_FILE */
4243
unsigned long fdt_addr;
4344
};
4445

@@ -62,6 +63,10 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
6263
const Elf_Shdr *relsec,
6364
const Elf_Shdr *symtab);
6465
#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add
66+
67+
struct kimage;
68+
int arch_kimage_file_post_load_cleanup(struct kimage *image);
69+
#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup
6570
#endif
6671

6772
#endif

arch/riscv/kernel/elf_kexec.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121
#include <linux/memblock.h>
2222
#include <asm/setup.h>
2323

24+
int arch_kimage_file_post_load_cleanup(struct kimage *image)
25+
{
26+
kvfree(image->arch.fdt);
27+
image->arch.fdt = NULL;
28+
29+
return kexec_image_post_load_cleanup_default(image);
30+
}
31+
2432
static int riscv_kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
2533
struct kexec_elf_info *elf_info, unsigned long old_pbase,
2634
unsigned long new_pbase)
@@ -298,6 +306,8 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
298306
pr_err("Error add DTB kbuf ret=%d\n", ret);
299307
goto out_free_fdt;
300308
}
309+
/* Cache the fdt buffer address for memory cleanup */
310+
image->arch.fdt = fdt;
301311
pr_notice("Loaded device tree at 0x%lx\n", kbuf.mem);
302312
goto out;
303313

0 commit comments

Comments
 (0)