From: Baoquan He bhe@redhat.com
commit b3e34a47f98974d0844444c5121aaff123004e57 upstream.
This is reported by kmemleak detector:
unreferenced object 0xffffc900002a9000 (size 4096): comm "kexec", pid 14950, jiffies 4295110793 (age 373.951s) hex dump (first 32 bytes): 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 .ELF............ 04 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 ..>............. backtrace: [<0000000016a8ef9f>] __vmalloc_node_range+0x101/0x170 [<000000002b66b6c0>] __vmalloc_node+0xb4/0x160 [<00000000ad40107d>] crash_prepare_elf64_headers+0x8e/0xcd0 [<0000000019afff23>] crash_load_segments+0x260/0x470 [<0000000019ebe95c>] bzImage64_load+0x814/0xad0 [<0000000093e16b05>] arch_kexec_kernel_image_load+0x1be/0x2a0 [<000000009ef2fc88>] kimage_file_alloc_init+0x2ec/0x5a0 [<0000000038f5a97a>] __do_sys_kexec_file_load+0x28d/0x530 [<0000000087c19992>] do_syscall_64+0x3b/0x90 [<0000000066e063a4>] entry_SYSCALL_64_after_hwframe+0x44/0xae
In crash_prepare_elf64_headers(), a buffer is allocated via vmalloc() to store elf headers. While it's not freed back to system correctly when kdump kernel is reloaded or unloaded. Then memory leak is caused. Fix it by introducing x86 specific function arch_kimage_file_post_load_cleanup(), and freeing the buffer there.
And also remove the incorrect elf header buffer freeing code. Before calling arch specific kexec_file loading function, the image instance has been initialized. So 'image->elf_headers' must be NULL. It doesn't make sense to free the elf header buffer in the place.
Three different people have reported three bugs about the memory leak on x86_64 inside Redhat.
Link: https://lkml.kernel.org/r/20220223113225.63106-2-bhe@redhat.com Signed-off-by: Baoquan He bhe@redhat.com Acked-by: Dave Young dyoung@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [Conflict due to 179350f00e06 ("x86: Use ELF fields defined in 'struct kimage'") not in the tree] Signed-off-by: Abdelkareem Abdelsaamad kareemem@amazon.com --- arch/x86/kernel/machine_kexec_64.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index a29a44a98e5b..19f6aafd595a 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -402,9 +402,6 @@ void machine_kexec(struct kimage *image) #ifdef CONFIG_KEXEC_FILE void *arch_kexec_kernel_image_load(struct kimage *image) { - vfree(image->arch.elf_headers); - image->arch.elf_headers = NULL; - if (!image->fops || !image->fops->load) return ERR_PTR(-ENOEXEC);
@@ -540,6 +537,15 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, (int)ELF64_R_TYPE(rel[i].r_info), value); return -ENOEXEC; } + +int arch_kimage_file_post_load_cleanup(struct kimage *image) +{ + vfree(image->arch.elf_headers); + image->arch.elf_headers = NULL; + image->arch.elf_headers_sz = 0; + + return kexec_image_post_load_cleanup_default(image); +} #endif /* CONFIG_KEXEC_FILE */
static int
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues: ⚠️ Found follow-up fixes in mainline
The upstream commit SHA1 provided is correct: b3e34a47f98974d0844444c5121aaff123004e57
WARNING: Author mismatch between patch and upstream commit: Backport author: Abdelkareem Abdelsaamadkareemem@amazon.com Commit author: Baoquan Hebhe@redhat.com
Status in newer kernel trees: 6.13.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (different SHA1: 8765a423a87d)
Found fixes commits: d00dd2f2645d x86/kexec: Fix double-free of elf header buffer
Note: The patch differs from the upstream commit: --- 1: b3e34a47f9897 ! 1: 2981ec404a4e1 x86/kexec: fix memory leak of elf header buffer @@ Metadata ## Commit message ## x86/kexec: fix memory leak of elf header buffer
+ commit b3e34a47f98974d0844444c5121aaff123004e57 upstream. + This is reported by kmemleak detector:
unreferenced object 0xffffc900002a9000 (size 4096): @@ Commit message Acked-by: Dave Young dyoung@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org + Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org + [Conflict due to + 179350f00e06 ("x86: Use ELF fields defined in 'struct kimage'") + not in the tree] + Signed-off-by: Abdelkareem Abdelsaamad kareemem@amazon.com
## arch/x86/kernel/machine_kexec_64.c ## @@ arch/x86/kernel/machine_kexec_64.c: void machine_kexec(struct kimage *image) #ifdef CONFIG_KEXEC_FILE void *arch_kexec_kernel_image_load(struct kimage *image) { -- vfree(image->elf_headers); -- image->elf_headers = NULL; +- vfree(image->arch.elf_headers); +- image->arch.elf_headers = NULL; - if (!image->fops || !image->fops->load) return ERR_PTR(-ENOEXEC); @@ arch/x86/kernel/machine_kexec_64.c: int arch_kexec_apply_relocations_add(struct + +int arch_kimage_file_post_load_cleanup(struct kimage *image) +{ -+ vfree(image->elf_headers); -+ image->elf_headers = NULL; -+ image->elf_headers_sz = 0; ++ vfree(image->arch.elf_headers); ++ image->arch.elf_headers = NULL; ++ image->arch.elf_headers_sz = 0; + + return kexec_image_post_load_cleanup_default(image); +} ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.10.y | Success | Success |
linux-stable-mirror@lists.linaro.org