As Baoquan and Catalin suggested, this patch set fixes
several pre-existing code issues found by Sashiko AI [1][2][3].
The major improvements and fixes included in this series are:
- Fix several memory leaks for arm64, and similar issues on LoongArch.
- Fix out-of-bounds write on 32-bit Highmem for x86.
- Fix TOCTOU race in crash memory range collection.
This patch set is rebased on v7.3-rc3. Compared to the previous version,
split out arm64 crash hotplug patches as Breno suggested, which are based
on these bugfix patches and will be resubmitted after this patch series
is merged.
Slightly tested on x86_64 and arm64 qemu with:
- kexec_load (--kexec-syscall --hotplug)
- kexec_load (--kexec-file-syscall)
All boot successfully into the second kernel.
[1]: https://lore.kernel.org/all/20260601094805.2928614-1-ruanjinjie@huawei.com/
[2]: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
[3]: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Changes in v6:
- Split out arm64 crash hotplug patches as Breno suggested.
- Remove unused elfcorehdr_updated [4].
- Make the patch split more clear.
- Link to v5: https://lore.kernel.org/all/20260918100442.3841135-1-ruanjinjie@huawei.com/
[4]: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Changs in v5:
- Rebased on v7.3-rc3.
- Fix several pre-existing code issues reported by Sashiko AI review. [3]
- Add an extra slot for memory hot-unplug.
- Add device_hotplug_lock_assert_held() helper.
- Rework to let the hotplug paths to skip CPU events entirely, which avoid
the TOCTOU race of memory hotplug events and internal CPU offline path
without holding device_hotplug_lock.
- Link to v4: https://lore.kernel.org/all/20260907125404.922123-1-ruanjinjie@huawei.com/
Changes in v4:
- Rebased on v7.3-rc1.
- Update the kexec_core code as Mike suggested.
- Update the LoongArch subject as Huacai suggested.
- Drop crash_dump_dm_crypt patch which will be fixed by Coiby in [4] as
Sourabh suggested.
- Drop x86 related patches because of branch conflict, which will
be done later.
- Drop the incorrect CRASH_MAX_MEMORY_RANGES patch.
- Handle elfcorehdr_index in arm64 arch code.
- Link to v3: https://lore.kernel.org/all/20260826092541.3905933-1-ruanjinjie@huawei.com/
[4] https://lore.kernel.org/all/20260828084900.1496839-2-coiby.xu@gmail.com/
Changes in v3:
- Handle "KEXEC_CRASH_HP_REMOVE_MEMORY" action.
- Fix several pre-existing code issues reported by Sashiko AI review [3].
- Introduce crash_extra_elfcorehdr_size() and elf64_phdr_size() helper.
- Rework related crash and arch code.
- Add test method.
- v2: https://lore.kernel.org/all/20260729031235.2840255-1-ruanjinjie@huawei.com/
Changes in v2:
- Split out Powerpc bugfix patch as Mike suggested.
- Use phys_to_virt() instead of __va() in update_crash_elfcorehdr().
- Convert pnum_hdr_sz() to a function.
- Only assign elfcorehdr_index after kexec_add_buffer succeeds, considering
crash_handle_hotplug_event() already performs validity check on
elfcorehdr_index:
- We can safely remove the check for CPU hotplug
in arch_crash_handle_hotplug_event().
- The elfcorehdr_index's segment mem will be valid in
update_crash_elfcorehdr(), so we can safely remove the NULL check.
- Simplify the commit message.
- v1: https://lore.kernel.org/all/20260723131242.1537633-1-ruanjinjie@huawei.com/#t
Jinjie Ruan (14):
kexec: Fix CMA segment address translation with non-zero text_offset
kexec: Record allocated CMA pages to fix release size mismatch
kexec: Extract kexec_free_segment_cma() from kimage_free_cma()
arm64: kexec_file: Fix CMA page leaks in segment placement retry loops
arm64: kexec_file: Fix elf_headers memory leak in retry loop
LoongArch: kexec_file: Fix CMA page leaks in segment placement retry
loops
LoongArch: kexec_file: Fix elf_headers memory leak in retry loop
LoongArch: kexec_file: Fix a modified_cmdline leak
x86/crash: Fix massive out-of-bounds write on 32-bit Highmem
crash: Extract crash_get_memory_ranges() helper
crash: Factor out crash_find_elfcorehdr() helper
crash: Normalize the kexec_load elfcorehdr at load time
driver core: Add device_hotplug_lock_assert_held() helper
crash: Fix TOCTOU race in crash memory range collection
arch/arm64/kernel/kexec_image.c | 1 +
arch/arm64/kernel/machine_kexec_file.c | 9 +-
arch/loongarch/kernel/kexec_efi.c | 1 +
arch/loongarch/kernel/machine_kexec.c | 2 +
arch/loongarch/kernel/machine_kexec_file.c | 10 +-
arch/powerpc/kexec/crash.c | 1 +
arch/x86/kernel/crash.c | 40 +++++---
drivers/base/core.c | 5 +
include/linux/crash_core.h | 2 +
include/linux/device.h | 1 +
include/linux/kexec.h | 4 +-
kernel/crash_core.c | 114 +++++++++++++++++----
kernel/kexec.c | 4 +
kernel/kexec_core.c | 43 +++++---
kernel/kexec_file.c | 13 ++-
15 files changed, 192 insertions(+), 58 deletions(-)
--
2.34.1
kimage_free_cma() relies on image->nr_segments to iterate over segments.
When an architecture loader (e.g., arm64) truncates nr_segments on a
mid-way failure, CMA pages allocated beyond the new boundary become
unreachable, causing silent memory leaks.
Extract the per-segment freeing logic into the exported helper
kexec_free_segment_cma(), so that architecture loaders can release
individual segments before nr_segments is truncated. Refactor
kimage_free_cma() to loop over the new helper, preserving existing
behavior.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Breno Leitao <leitao@debian.org>
Signed-off-by: Jinjie Ruan <redacted>
---
include/linux/kexec.h | 2 ++
kernel/kexec_core.c | 27 +++++++++++++++------------
2 files changed, 17 insertions(+), 12 deletions(-)
During kexec image placement retry loops, any midway failure causes
the loader to truncate `image->nr_segments` back to its initial state
to purge the failed segments.
However, this truncation introduces a memory leak. The CMA pages
allocated via kexec_add_buffer() during the failed attempt are tracked
in the `image->segment_cma` array. Because the subsequent cleanup paths
only iterate up to the truncated `nr_segments` boundary, these allocated
CMA pages outside the new boundary are permanently leaked.
Fix this by explicitly releasing the associated CMA buffers in
the failure paths before `image->nr_segments` is reduced.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Breno Leitao <leitao@debian.org>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yeoreum Yun <redacted>
Cc: Baoquan He <redacted>
Cc: stable@vger.kernel.org
Fixes: 07d24902977e4 ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <redacted>
---
arch/arm64/kernel/kexec_image.c | 1 +
arch/arm64/kernel/machine_kexec_file.c | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
Factor out the crash memory range collection logic from
crash_prepare_headers() into a separate function. This allows
the memory hotplug path to obtain and modify the range list
(e.g. remove offlined memory) before generating the elfcorehdr.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Signed-off-by: Jinjie Ruan <redacted>
---
include/linux/crash_core.h | 1 +
kernel/crash_core.c | 22 +++++++++++++++++++---
2 files changed, 20 insertions(+), 3 deletions(-)
@@ -317,8 +317,7 @@ int crash_exclude_core_ranges(struct crash_mem **cmem)return0;}-intcrash_prepare_headers(intneed_kernel_map,void**addr,unsignedlong*sz,-unsignedlong*nr_mem_ranges)+intcrash_get_memory_ranges(structcrash_mem**mem_ranges){unsignedintmax_nr_ranges;structcrash_mem*cmem;
@@ -344,13 +343,30 @@ int crash_prepare_headers(int need_kernel_map, void **addr, unsigned long *sz,if(ret)gotoout;+*mem_ranges=cmem;+return0;++out:+kvfree(cmem);+returnret;+}++intcrash_prepare_headers(intneed_kernel_map,void**addr,unsignedlong*sz,+unsignedlong*nr_mem_ranges)+{+structcrash_mem*cmem=NULL;+intret;++ret=crash_get_memory_ranges(&cmem);+if(ret)+returnret;+/* Return the computed number of memory ranges, for hotplug usage */if(nr_mem_ranges)*nr_mem_ranges=cmem->nr_ranges;ret=crash_prepare_elf64_headers(cmem,need_kernel_map,addr,sz);-out:kvfree(cmem);returnret;}
For kexec_load() the kernel does not build the elfcorehdr, so it is only
rewritten by the first crash hotplug event. CPU hotplug events do not
change the elfcorehdr, but they may run without device_hotplug_lock
(e.g. CPU offlining during suspend), so they cannot perform that rewrite
without racing with memory hotplug.
Normalize the elfcorehdr once when the crash image is installed via
crash_hotplug_prepare_elfcorehdr(), while device_hotplug_lock can still
be taken safely, and let the hotplug paths skip CPU events entirely.
Architectures that do not need the rewrite (e.g. powerpc) treat
KEXEC_CRASH_HP_NONE as a no-op.
The x86 crash hotplug handler now skips CPU hotplug events
unconditionally, so nothing reads image->elfcorehdr_updated anymore.
Drop the field and the code that maintains it.
Slightly tested on x86_64 with kexec_load (--kexec-syscall --hotplug),
it boots successfully into the second kernel.
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: "Christophe Leroy (CS GROUP)" <chleroy@kernel.org>
Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: Shrikanth Hegde <sshegde@linux.ibm.com>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Cc: Sourabh Jain <redacted>
Signed-off-by: Jinjie Ruan <redacted>
---
arch/powerpc/kexec/crash.c | 1 +
arch/x86/kernel/crash.c | 5 ++---
include/linux/crash_core.h | 1 +
include/linux/kexec.h | 1 -
kernel/crash_core.c | 20 +++++++++++++++++++-
kernel/kexec.c | 4 ++++
kernel/kexec_core.c | 1 -
7 files changed, 27 insertions(+), 6 deletions(-)
@@ -742,7 +742,6 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,/* No longer handling a hotplug event */image->hp_action=KEXEC_CRASH_HP_NONE;-image->elfcorehdr_updated=true;/* Change back to read-only */arch_kexec_protect_crashkres();
@@ -754,6 +753,25 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,crash_hotplug_unlock();}+voidcrash_hotplug_prepare_elfcorehdr(structkimage*image)+{+if(!image||!image->hotplug_support||image->file_mode)+return;++crash_find_elfcorehdr(image);+if(image->elfcorehdr_index<0)+return;++/*+*kexec_load()imagesarenotnormalizedatload,sodoitherewhile+*thelockisstillfreetotake.hp_actionisKEXEC_CRASH_HP_NONE,+*whichthearchhandlertreatsas"just rebuild the elfcorehdr".+*/+lock_device_hotplug();+arch_crash_handle_hotplug_event(image,NULL);+unlock_device_hotplug();+}+staticintcrash_memhp_notifier(structnotifier_block*nb,unsignedlongval,void*arg){switch(val){
@@ -166,6 +166,10 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,/* Install the new kernel and uninstall the old */image=xchg(dest_image,image);+#ifdef CONFIG_CRASH_HOTPLUG+if((flags&KEXEC_ON_CRASH)&&kexec_crash_image)+crash_hotplug_prepare_elfcorehdr(kexec_crash_image);+#endifout:#ifdef CONFIG_CRASH_DUMPif((flags&KEXEC_ON_CRASH)&&kexec_crash_image)
The elfcorehdr segment is located by scanning the segments for
the ELF magic. Factor that scan out into a new helper function,
crash_find_elfcorehdr(), to clean up crash_handle_hotplug_event()
and prepare for its reuse in crash hotplug code.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Cc: Breno Leitao <leitao@debian.org>
Signed-off-by: Jinjie Ruan <redacted>
---
kernel/crash_core.c | 39 +++++++++++++++++++++++----------------
1 file changed, 23 insertions(+), 16 deletions(-)
The CMA pages allocated for a kexec segment are released using the
segment's memsz to calculate the number of pages. However, some
architecture loaders modify the segment's memsz after allocation
(e.g. arm64 subtracts text_offset), causing the release function to
free fewer pages than were originally allocated, leaking the remaining
CMA pages.
Add a per-segment `segment_cma_pages` array to store the number of
pages actually allocated from CMA. Populate it during
kexec_add_buffer() using the aligned memsz, and use it in
kimage_free_cma() to accurately release all allocated pages.
This avoids relying on the potentially modified segment->memsz and
prevents silent CMA memory leaks.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Brian Mak <redacted>
Cc: Pingfan Liu <redacted>
Cc: Sourabh Jain <redacted>
Cc: Justinien Bouron <redacted>
Cc: Li Chen <redacted>
Cc: Breno Leitao <leitao@debian.org>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <redacted>
---
include/linux/kexec.h | 1 +
kernel/kexec_core.c | 7 ++++---
kernel/kexec_file.c | 13 +++++++++----
3 files changed, 14 insertions(+), 7 deletions(-)
@@ -670,7 +670,7 @@ static int kexec_walk_resources(struct kexec_buf *kbuf,staticintkexec_alloc_contig(structkexec_buf*kbuf){-size_tnr_pages=kbuf->memsz>>PAGE_SHIFT;+size_tnr_pages=PFN_DOWN(kbuf->memsz);unsignedlongmem;structpage*p;
@@ -756,14 +756,16 @@ int kexec_locate_mem_hole(struct kexec_buf *kbuf)*/intkexec_add_buffer(structkexec_buf*kbuf){+unsignedlongnr_segments=kbuf->image->nr_segments;structkexec_segment*ksegment;+size_tnr_cma_pages=0;intret;/* Currently adding segment this way is allowed only in file mode */if(!kbuf->image->file_mode)return-EINVAL;-if(kbuf->image->nr_segments>=KEXEC_SEGMENT_MAX)+if(nr_segments>=KEXEC_SEGMENT_MAX)return-EINVAL;/*
@@ -789,12 +791,15 @@ int kexec_add_buffer(struct kexec_buf *kbuf)returnret;/* Found a suitable memory range */-ksegment=&kbuf->image->segment[kbuf->image->nr_segments];+ksegment=&kbuf->image->segment[nr_segments];ksegment->kbuf=kbuf->buffer;ksegment->bufsz=kbuf->bufsz;ksegment->mem=kbuf->mem;ksegment->memsz=kbuf->memsz;-kbuf->image->segment_cma[kbuf->image->nr_segments]=kbuf->cma;+kbuf->image->segment_cma[nr_segments]=kbuf->cma;+if(kbuf->cma)+nr_cma_pages=PFN_DOWN(kbuf->memsz);+kbuf->image->segment_cma_pages[nr_segments]=nr_cma_pages;kbuf->image->nr_segments++;return0;}
If load_other_segments() fails after image->elf_headers is assigned,
the memory lifecycle is safely managed by the global kimage object
and will be freed in arch_kimage_file_post_load_cleanup().
However, during a retry loop in image_load(), a subsequent iteration
will allocate a new buffer and overwrite image->elf_headers. This
permanently leaks the stale memory from the previous iteration before
the global cleanup can track it.
Fix this by explicitly freeing the stale `image->elf_headers` buffer
before assigning the newly allocated headers.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Thomas Huth <redacted>
Cc: Breno Leitao <leitao@debian.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yeoreum Yun <redacted>
Cc: Baoquan He <redacted>
Cc: stable@vger.kernel.org
Fixes: 108aa503657e ("arm64: kexec_file: try more regions if loading segments fails")
Signed-off-by: Jinjie Ruan <redacted>
---
arch/arm64/kernel/machine_kexec_file.c | 4 ++++
1 file changed, 4 insertions(+)
kimage_load_cma_segment() and kimage_map_segment() both translate
a CMA segment using page_address(cma), which returns the CMA base
address. This ignores segment->mem.
On arm64, image_load() adds text_offset to segment->mem before the
segment is loaded:
kernel_segment->mem += text_offset;
kernel_segment->memsz -= text_offset;
image->start = kernel_segment->mem;
so segment->mem no longer matches the CMA base. The kernel payload is
therefore copied to the wrong offset, while image->start points past
it, and kexec jumps into the middle of the kernel.
kimage_map_segment() has the same problem for any CMA segment whose
mem has been moved.
Add kimage_cma_vaddr() to translate a boot physical address inside a
CMA segment to its virtual address, and use it in both places.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Pingfan Liu <redacted>
Cc: Justinien Bouron <redacted>
Cc: Sourabh Jain <redacted>
Cc: Breno Leitao <leitao@debian.org>
Cc: stable@vger.kernel.org
Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <redacted>
---
kernel/kexec_core.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
crash_get_memory_ranges() walks memblock, which memory hotplug
modifies under device_hotplug_lock. A caller that does not hold
the lock can race with memblock_double_array() and iterate a freed
regions array.
Add device_hotplug_lock_assert_held() so that crash code can
use it to catch such unsafe callers via lockdep.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Jinjie Ruan <redacted>
---
drivers/base/core.c | 5 +++++
include/linux/device.h | 1 +
2 files changed, 6 insertions(+)
The crash kernel ELF core header construction counts system memory
ranges via `arch_get_system_nr_ranges()`, allocates the crash_mem
buffer, and then populates it via `arch_crash_populate_cmem()`.
This sequence has a time-of-check-to-time-of-use (TOCTOU) race with
memory hotplug: a concurrent hotplug event between the count
and populate steps can increase the number of ranges beyond the allocated
capacity, causing an out-of-bounds write. If the event triggers
memblock_double_array(), the memblock array can be freed and reallocated
during iteration, leading to a use-after-free.
Protect the entire range collection with device_hotplug_lock. Since
the hotplug notification path already holds that lock, add a lockless
helper, crash_get_memory_ranges_nolock(), for use there. The regular
crash_get_memory_ranges() acquires the lock and calls the helper.
Cc: stable@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Cc: AKASHI Takahiro <redacted>
Cc: Will Deacon <will@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Palmer Dabbelt <redacted>
Cc: Youling Tang <redacted>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Breno Leitao <leitao@debian.org>
Fixes: 8d5f894a3108 ("x86: kexec_file: lift CRASH_MAX_RANGES limit on crash_mem buffer")
Fixes: 3751e728cef2 ("arm64: kexec_file: add crash dump support")
Fixes: 8acea455fafa ("RISC-V: Support for kexec_file on panic")
Fixes: 1bcca8620a91 ("LoongArch: Add crash dump support for kexec_file")
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Signed-off-by: Jinjie Ruan <redacted>
---
arch/x86/kernel/crash.c | 9 ++++++++-
include/linux/crash_core.h | 2 +-
kernel/crash_core.c | 35 ++++++++++++++++++++++++++++++++++-
3 files changed, 43 insertions(+), 3 deletions(-)
@@ -447,6 +447,7 @@ unsigned int arch_crash_get_elfcorehdr_size(void)*/voidarch_crash_handle_hotplug_event(structkimage*image,void*arg){+structcrash_mem*cmem=NULL;unsignedlongmem,memsz;unsignedlongelfsz=0;void*elfbuf=NULL;
@@ -461,11 +462,16 @@ void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)image->hp_action==KEXEC_CRASH_HP_REMOVE_CPU)return;+if(crash_get_memory_ranges_nolock(&cmem)){+pr_err("Failed to get crash mem range\n");+gotoout;+}+/**CreatethenewelfcorehdrreflectingthechangestoCPUand/or*memoryresources.*/-if(crash_prepare_headers(IS_ENABLED(CONFIG_X86_64),&elfbuf,&elfsz,NULL)){+if(crash_prepare_elf64_headers(cmem,IS_ENABLED(CONFIG_X86_64),&elfbuf,&elfsz)){pr_err("unable to create new elfcorehdr");gotoout;}
If load_other_segments() fails after image->elf_headers is assigned,
the memory lifecycle is safely managed by the global kimage object
and will be freed in arch_kimage_file_post_load_cleanup().
However, during a retry loop in efi_kexec_load(), a subsequent iteration
will allocate a new buffer and overwrite image->elf_headers. This
permanently leaks the stale memory from the previous iteration before
the global cleanup can track it.
Fix this by explicitly freeing the stale `image->elf_headers` buffer
before assigning the newly allocated headers.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: Youling Tang <redacted>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Sourabh Jain <redacted>
Cc: Kees Cook <kees@kernel.org>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Fixes: 55d990f0084c ("LoongArch: Add EFI binary support for kexec_file")
Signed-off-by: Jinjie Ruan <redacted>
---
arch/loongarch/kernel/machine_kexec_file.c | 4 ++++
1 file changed, 4 insertions(+)
During kexec image placement retry loops, any midway failure causes
the loader to truncate `image->nr_segments` back to its initial state
to purge the failed segments.
However, this truncation introduces a memory leak. The CMA pages
allocated via kexec_add_buffer() during the failed attempt are tracked
in the `image->segment_cma` array. Because the subsequent cleanup paths
only iterate up to the truncated `nr_segments` boundary, these allocated
CMA pages outside the new boundary are permanently leaked.
Fix this by explicitly releasing the associated CMA buffers in
the failure paths before `image->nr_segments` is reduced.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: Youling Tang <redacted>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Sourabh Jain <redacted>
Cc: Kees Cook <kees@kernel.org>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Fixes: 55d990f0084c ("LoongArch: Add EFI binary support for kexec_file")
Signed-off-by: Jinjie Ruan <redacted>
---
arch/loongarch/kernel/kexec_efi.c | 1 +
arch/loongarch/kernel/machine_kexec_file.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
load_other_segments() allocates modified_cmdline and stores it in
image->arch.cmdline_ptr. machine_kexec_prepare() then copies it to
KEXEC_CMDLINE_ADDR and overwrites the pointer, so the heap buffer is
leaked on every successful kexec_file_load().
Free the buffer after the copy.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: Kexin Liu <redacted>
Cc: Youling Tang <redacted>
Cc: Qiang Ma <redacted>
Cc: Tianyang Zhang <redacted>
Cc: George Guo <redacted>
Cc: stable@vger.kernel.org
Fixes: d162feec6b6e ("LoongArch: Add preparatory infrastructure for kexec_file")
Signed-off-by: Jinjie Ruan <redacted>
---
arch/loongarch/kernel/machine_kexec.c | 2 ++
1 file changed, 2 insertions(+)
@@ -56,6 +57,7 @@ int machine_kexec_prepare(struct kimage *kimage)*/memcpy((void*)KEXEC_CMDLINE_ADDR,(void*)kimage->arch.cmdline_ptr,strlen((char*)kimage->arch.cmdline_ptr)+1);+kfree((void*)kimage->arch.cmdline_ptr);kimage->arch.cmdline_ptr=(unsignedlong)KEXEC_CMDLINE_ADDR;}else{/* Find the command line */
On 32-bit x86 systems with HIGHMEM, kmap_local_page() only maps a single
4KB page. However, the elfcorehdr segment can span several pages (up to
hundreds of kilobytes).
The original code blindly copies 'elfsz' bytes at once via
memcpy_flushcache(), overwriting adjacent fixmap entries or critical
virtual addresses.
Fix this by copying the new elfcorehdr page by page.
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Chao Gao <redacted>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Eric DeVolder <redacted>
Cc: Hari Bathini <hbathini@linux.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Sourabh Jain <redacted>
Cc: stable@vger.kernel.org
Fixes: ea53ad9cf73b ("x86/crash: add x86 crash hotplug support")
Link: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Signed-off-by: Jinjie Ruan <redacted>
---
arch/x86/kernel/crash.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
On 32-bit x86 systems with HIGHMEM, kmap_local_page() only maps a single
4KB page. However, the elfcorehdr segment can span several pages (up to
hundreds of kilobytes).
The original code blindly copies 'elfsz' bytes at once via
memcpy_flushcache(), overwriting adjacent fixmap entries or critical
virtual addresses.
Fix this by copying the new elfcorehdr page by page.
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Chao Gao <redacted>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Eric DeVolder <redacted>
Cc: Hari Bathini <hbathini@linux.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Sourabh Jain <redacted>
Cc: stable@vger.kernel.org
Fixes: ea53ad9cf73b ("x86/crash: add x86 crash hotplug support")
Link: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Signed-off-by: Jinjie Ruan <redacted>
During kexec image placement retry loops, any midway failure causes
the loader to truncate `image->nr_segments` back to its initial state
to purge the failed segments.
However, this truncation introduces a memory leak. The CMA pages
allocated via kexec_add_buffer() during the failed attempt are tracked
in the `image->segment_cma` array. Because the subsequent cleanup paths
only iterate up to the truncated `nr_segments` boundary, these allocated
CMA pages outside the new boundary are permanently leaked.
Fix this by explicitly releasing the associated CMA buffers in
the failure paths before `image->nr_segments` is reduced.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: Youling Tang <redacted>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Sourabh Jain <redacted>
Cc: Kees Cook <kees@kernel.org>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Fixes: 55d990f0084c ("LoongArch: Add EFI binary support for kexec_file")
Signed-off-by: Jinjie Ruan <redacted>
kimage_free_cma() relies on image->nr_segments to iterate over segments.
When an architecture loader (e.g., arm64) truncates nr_segments on a
mid-way failure, CMA pages allocated beyond the new boundary become
unreachable, causing silent memory leaks.
Extract the per-segment freeing logic into the exported helper
kexec_free_segment_cma(), so that architecture loaders can release
individual segments before nr_segments is truncated. Refactor
kimage_free_cma() to loop over the new helper, preserving existing
behavior.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Breno Leitao <leitao@debian.org>
Signed-off-by: Jinjie Ruan <redacted>
If load_other_segments() fails after image->elf_headers is assigned,
the memory lifecycle is safely managed by the global kimage object
and will be freed in arch_kimage_file_post_load_cleanup().
However, during a retry loop in efi_kexec_load(), a subsequent iteration
will allocate a new buffer and overwrite image->elf_headers. This
permanently leaks the stale memory from the previous iteration before
the global cleanup can track it.
Fix this by explicitly freeing the stale `image->elf_headers` buffer
before assigning the newly allocated headers.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: Youling Tang <redacted>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Sourabh Jain <redacted>
Cc: Kees Cook <kees@kernel.org>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Fixes: 55d990f0084c ("LoongArch: Add EFI binary support for kexec_file")
Signed-off-by: Jinjie Ruan <redacted>
The CMA pages allocated for a kexec segment are released using the
segment's memsz to calculate the number of pages. However, some
architecture loaders modify the segment's memsz after allocation
(e.g. arm64 subtracts text_offset), causing the release function to
free fewer pages than were originally allocated, leaking the remaining
CMA pages.
Add a per-segment `segment_cma_pages` array to store the number of
pages actually allocated from CMA. Populate it during
kexec_add_buffer() using the aligned memsz, and use it in
kimage_free_cma() to accurately release all allocated pages.
This avoids relying on the potentially modified segment->memsz and
prevents silent CMA memory leaks.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Brian Mak <redacted>
Cc: Pingfan Liu <redacted>
Cc: Sourabh Jain <redacted>
Cc: Justinien Bouron <redacted>
Cc: Li Chen <redacted>
Cc: Breno Leitao <leitao@debian.org>
Cc: stable@vger.kernel.org
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <redacted>
If load_other_segments() fails after image->elf_headers is assigned,
the memory lifecycle is safely managed by the global kimage object
and will be freed in arch_kimage_file_post_load_cleanup().
However, during a retry loop in image_load(), a subsequent iteration
will allocate a new buffer and overwrite image->elf_headers. This
permanently leaks the stale memory from the previous iteration before
the global cleanup can track it.
Fix this by explicitly freeing the stale `image->elf_headers` buffer
before assigning the newly allocated headers.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Thomas Huth <redacted>
Cc: Breno Leitao <leitao@debian.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yeoreum Yun <redacted>
Cc: Baoquan He <redacted>
Cc: stable@vger.kernel.org
Fixes: 108aa503657e ("arm64: kexec_file: try more regions if loading segments fails")
Signed-off-by: Jinjie Ruan <redacted>
load_other_segments() allocates modified_cmdline and stores it in
image->arch.cmdline_ptr. machine_kexec_prepare() then copies it to
KEXEC_CMDLINE_ADDR and overwrites the pointer, so the heap buffer is
leaked on every successful kexec_file_load().
Free the buffer after the copy.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: Kexin Liu <redacted>
Cc: Youling Tang <redacted>
Cc: Qiang Ma <redacted>
Cc: Tianyang Zhang <redacted>
Cc: George Guo <redacted>
Cc: stable@vger.kernel.org
Fixes: d162feec6b6e ("LoongArch: Add preparatory infrastructure for kexec_file")
Signed-off-by: Jinjie Ruan <redacted>
The elfcorehdr segment is located by scanning the segments for
the ELF magic. Factor that scan out into a new helper function,
crash_find_elfcorehdr(), to clean up crash_handle_hotplug_event()
and prepare for its reuse in crash hotplug code.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Cc: Breno Leitao <leitao@debian.org>
Signed-off-by: Jinjie Ruan <redacted>
kimage_load_cma_segment() and kimage_map_segment() both translate
a CMA segment using page_address(cma), which returns the CMA base
address. This ignores segment->mem.
On arm64, image_load() adds text_offset to segment->mem before the
segment is loaded:
kernel_segment->mem += text_offset;
kernel_segment->memsz -= text_offset;
image->start = kernel_segment->mem;
so segment->mem no longer matches the CMA base. The kernel payload is
therefore copied to the wrong offset, while image->start points past
it, and kexec jumps into the middle of the kernel.
[ ... ]
Cc: Sourabh Jain <redacted>
Cc: Breno Leitao <leitao@debian.org>
Cc: stable@vger.kernel.org
Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <redacted>
crash_get_memory_ranges() walks memblock, which memory hotplug
modifies under device_hotplug_lock. A caller that does not hold
the lock can race with memblock_double_array() and iterate a freed
regions array.
Add device_hotplug_lock_assert_held() so that crash code can
use it to catch such unsafe callers via lockdep.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Jinjie Ruan <redacted>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] mm: kexec_file_load infinite loop due to unconstrained CMA retry
--
commit 897e1cdce0bd14dc7b700f2043c1f14c66a40791
Author: Jinjie Ruan [off-list ref]
arm64: kexec_file: Fix CMA page leaks in segment placement retry loops
This commit fixes a memory leak in the kexec image placement retry loop.
It explicitly releases the associated CMA buffers in the failure paths
before the segment count is reduced.
[Severity: High]
Does freeing the CMA segment here create an infinite loop?
The loop updates kbuf.buf_min to search past the current kernel segment
expecting the next kexec_add_buffer() call to allocate from a new hole.
However, kexec_alloc_contig() allocates via CMA:
kernel/kexec_file.c:kexec_alloc_contig() {
...
p = dma_alloc_from_contiguous(NULL, nr_pages,
get_order(kbuf->buf_align), true);
...
}
The underlying CMA allocator completely ignores kbuf->buf_min and
kbuf->buf_max. Since the CMA block was just freed, the allocator will
repeatedly return the exact same physically contiguous block.
If load_other_segments() fails due to layout constraints (like dtb or
initrd placement), it will run again with the identical memory layout, fail
for the exact same reason, and loop infinitely causing a system hang.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=4
Factor out the crash memory range collection logic from
crash_prepare_headers() into a separate function. This allows
the memory hotplug path to obtain and modify the range list
(e.g. remove offlined memory) before generating the elfcorehdr.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Signed-off-by: Jinjie Ruan <redacted>
For kexec_load() the kernel does not build the elfcorehdr, so it is only
rewritten by the first crash hotplug event. CPU hotplug events do not
change the elfcorehdr, but they may run without device_hotplug_lock
(e.g. CPU offlining during suspend), so they cannot perform that rewrite
without racing with memory hotplug.
Normalize the elfcorehdr once when the crash image is installed via
crash_hotplug_prepare_elfcorehdr(), while device_hotplug_lock can still
be taken safely, and let the hotplug paths skip CPU events entirely.
Architectures that do not need the rewrite (e.g. powerpc) treat
KEXEC_CRASH_HP_NONE as a no-op.
The x86 crash hotplug handler now skips CPU hotplug events
unconditionally, so nothing reads image->elfcorehdr_updated anymore.
Drop the field and the code that maintains it.
[ ... ]
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Cc: Sourabh Jain <redacted>
Signed-off-by: Jinjie Ruan <redacted>
The crash kernel ELF core header construction counts system memory
ranges via `arch_get_system_nr_ranges()`, allocates the crash_mem
buffer, and then populates it via `arch_crash_populate_cmem()`.
This sequence has a time-of-check-to-time-of-use (TOCTOU) race with
memory hotplug: a concurrent hotplug event between the count
and populate steps can increase the number of ranges beyond the allocated
capacity, causing an out-of-bounds write. If the event triggers
memblock_double_array(), the memblock array can be freed and reallocated
during iteration, leading to a use-after-free.
Protect the entire range collection with device_hotplug_lock. Since
the hotplug notification path already holds that lock, add a lockless
helper, crash_get_memory_ranges_nolock(), for use there. The regular
crash_get_memory_ranges() acquires the lock and calls the helper.
[ ... ]
Fixes: 3751e728cef2 ("arm64: kexec_file: add crash dump support")
Fixes: 8acea455fafa ("RISC-V: Support for kexec_file on panic")
Fixes: 1bcca8620a91 ("LoongArch: Add crash dump support for kexec_file")
Link: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
Signed-off-by: Jinjie Ruan <redacted>
As Baoquan and Catalin suggested, this patch set fixes
several pre-existing code issues found by Sashiko AI [1][2][3].
The major improvements and fixes included in this series are:
- Fix several memory leaks for arm64, and similar issues on LoongArch.
- Fix out-of-bounds write on 32-bit Highmem for x86.
- Fix TOCTOU race in crash memory range collection.
Hi all,
Gentle ping.
Could anyone take a look or let me know if there's anything
else needed? I can rebase/resend if required.
This patch set is rebased on v7.3-rc3. Compared to the previous version,
split out arm64 crash hotplug patches as Breno suggested, which are based
on these bugfix patches and will be resubmitted after this patch series
is merged.
Slightly tested on x86_64 and arm64 qemu with:
- kexec_load (--kexec-syscall --hotplug)
- kexec_load (--kexec-file-syscall)
All boot successfully into the second kernel.
[1]: https://lore.kernel.org/all/20260601094805.2928614-1-ruanjinjie@huawei.com/
[2]: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
[3]: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Changes in v6:
- Split out arm64 crash hotplug patches as Breno suggested.
- Remove unused elfcorehdr_updated [4].
- Make the patch split more clear.
- Link to v5: https://lore.kernel.org/all/20260918100442.3841135-1-ruanjinjie@huawei.com/
[4]: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Changs in v5:
- Rebased on v7.3-rc3.
- Fix several pre-existing code issues reported by Sashiko AI review. [3]
- Add an extra slot for memory hot-unplug.
- Add device_hotplug_lock_assert_held() helper.
- Rework to let the hotplug paths to skip CPU events entirely, which avoid
the TOCTOU race of memory hotplug events and internal CPU offline path
without holding device_hotplug_lock.
- Link to v4: https://lore.kernel.org/all/20260907125404.922123-1-ruanjinjie@huawei.com/
Changes in v4:
- Rebased on v7.3-rc1.
- Update the kexec_core code as Mike suggested.
- Update the LoongArch subject as Huacai suggested.
- Drop crash_dump_dm_crypt patch which will be fixed by Coiby in [4] as
Sourabh suggested.
- Drop x86 related patches because of branch conflict, which will
be done later.
- Drop the incorrect CRASH_MAX_MEMORY_RANGES patch.
- Handle elfcorehdr_index in arm64 arch code.
- Link to v3: https://lore.kernel.org/all/20260826092541.3905933-1-ruanjinjie@huawei.com/
[4] https://lore.kernel.org/all/20260828084900.1496839-2-coiby.xu@gmail.com/
Changes in v3:
- Handle "KEXEC_CRASH_HP_REMOVE_MEMORY" action.
- Fix several pre-existing code issues reported by Sashiko AI review [3].
- Introduce crash_extra_elfcorehdr_size() and elf64_phdr_size() helper.
- Rework related crash and arch code.
- Add test method.
- v2: https://lore.kernel.org/all/20260729031235.2840255-1-ruanjinjie@huawei.com/
Changes in v2:
- Split out Powerpc bugfix patch as Mike suggested.
- Use phys_to_virt() instead of __va() in update_crash_elfcorehdr().
- Convert pnum_hdr_sz() to a function.
- Only assign elfcorehdr_index after kexec_add_buffer succeeds, considering
crash_handle_hotplug_event() already performs validity check on
elfcorehdr_index:
- We can safely remove the check for CPU hotplug
in arch_crash_handle_hotplug_event().
- The elfcorehdr_index's segment mem will be valid in
update_crash_elfcorehdr(), so we can safely remove the NULL check.
- Simplify the commit message.
- v1: https://lore.kernel.org/all/20260723131242.1537633-1-ruanjinjie@huawei.com/#t
Jinjie Ruan (14):
kexec: Fix CMA segment address translation with non-zero text_offset
kexec: Record allocated CMA pages to fix release size mismatch
kexec: Extract kexec_free_segment_cma() from kimage_free_cma()
arm64: kexec_file: Fix CMA page leaks in segment placement retry loops
arm64: kexec_file: Fix elf_headers memory leak in retry loop
LoongArch: kexec_file: Fix CMA page leaks in segment placement retry
loops
LoongArch: kexec_file: Fix elf_headers memory leak in retry loop
LoongArch: kexec_file: Fix a modified_cmdline leak
x86/crash: Fix massive out-of-bounds write on 32-bit Highmem
crash: Extract crash_get_memory_ranges() helper
crash: Factor out crash_find_elfcorehdr() helper
crash: Normalize the kexec_load elfcorehdr at load time
driver core: Add device_hotplug_lock_assert_held() helper
crash: Fix TOCTOU race in crash memory range collection
arch/arm64/kernel/kexec_image.c | 1 +
arch/arm64/kernel/machine_kexec_file.c | 9 +-
arch/loongarch/kernel/kexec_efi.c | 1 +
arch/loongarch/kernel/machine_kexec.c | 2 +
arch/loongarch/kernel/machine_kexec_file.c | 10 +-
arch/powerpc/kexec/crash.c | 1 +
arch/x86/kernel/crash.c | 40 +++++---
drivers/base/core.c | 5 +
include/linux/crash_core.h | 2 +
include/linux/device.h | 1 +
include/linux/kexec.h | 4 +-
kernel/crash_core.c | 114 +++++++++++++++++----
kernel/kexec.c | 4 +
kernel/kexec_core.c | 43 +++++---
kernel/kexec_file.c | 13 ++-
15 files changed, 192 insertions(+), 58 deletions(-)
From: Baoquan He <baoquan.he@linux.dev> Date: 2026-10-08 03:26:57
On 10/08/26 at 09:57am, Jinjie Ruan wrote:
在 2026/9/21 17:04, Jinjie Ruan 写道:
quoted
As Baoquan and Catalin suggested, this patch set fixes
several pre-existing code issues found by Sashiko AI [1][2][3].
The major improvements and fixes included in this series are:
- Fix several memory leaks for arm64, and similar issues on LoongArch.
- Fix out-of-bounds write on 32-bit Highmem for x86.
- Fix TOCTOU race in crash memory range collection.
Hi all,
Gentle ping.
Could anyone take a look or let me know if there's anything
else needed? I can rebase/resend if required.
They may need reviewing and ack from different arch. E.g patch 1,
even though it's changed in kernel/kexec_core.c, the arm64 specific
handling need be checked and confirmed by arm64 expert.
I can review changes in generic code and arch I am familiar with, while
those part I am unfamiliar with need be reviewed by experts of specific
area.
quoted
This patch set is rebased on v7.3-rc3. Compared to the previous version,
split out arm64 crash hotplug patches as Breno suggested, which are based
on these bugfix patches and will be resubmitted after this patch series
is merged.
Slightly tested on x86_64 and arm64 qemu with:
- kexec_load (--kexec-syscall --hotplug)
- kexec_load (--kexec-file-syscall)
All boot successfully into the second kernel.
[1]: https://lore.kernel.org/all/20260601094805.2928614-1-ruanjinjie@huawei.com/
[2]: https://sashiko.dev/#/patchset/20260729031235.2840255-1-ruanjinjie%40huawei.com
[3]: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Changes in v6:
- Split out arm64 crash hotplug patches as Breno suggested.
- Remove unused elfcorehdr_updated [4].
- Make the patch split more clear.
- Link to v5: https://lore.kernel.org/all/20260918100442.3841135-1-ruanjinjie@huawei.com/
[4]: https://sashiko.dev/#/patchset/20260907125404.922123-1-ruanjinjie%40huawei.com
Changs in v5:
- Rebased on v7.3-rc3.
- Fix several pre-existing code issues reported by Sashiko AI review. [3]
- Add an extra slot for memory hot-unplug.
- Add device_hotplug_lock_assert_held() helper.
- Rework to let the hotplug paths to skip CPU events entirely, which avoid
the TOCTOU race of memory hotplug events and internal CPU offline path
without holding device_hotplug_lock.
- Link to v4: https://lore.kernel.org/all/20260907125404.922123-1-ruanjinjie@huawei.com/
Changes in v4:
- Rebased on v7.3-rc1.
- Update the kexec_core code as Mike suggested.
- Update the LoongArch subject as Huacai suggested.
- Drop crash_dump_dm_crypt patch which will be fixed by Coiby in [4] as
Sourabh suggested.
- Drop x86 related patches because of branch conflict, which will
be done later.
- Drop the incorrect CRASH_MAX_MEMORY_RANGES patch.
- Handle elfcorehdr_index in arm64 arch code.
- Link to v3: https://lore.kernel.org/all/20260826092541.3905933-1-ruanjinjie@huawei.com/
[4] https://lore.kernel.org/all/20260828084900.1496839-2-coiby.xu@gmail.com/
Changes in v3:
- Handle "KEXEC_CRASH_HP_REMOVE_MEMORY" action.
- Fix several pre-existing code issues reported by Sashiko AI review [3].
- Introduce crash_extra_elfcorehdr_size() and elf64_phdr_size() helper.
- Rework related crash and arch code.
- Add test method.
- v2: https://lore.kernel.org/all/20260729031235.2840255-1-ruanjinjie@huawei.com/
Changes in v2:
- Split out Powerpc bugfix patch as Mike suggested.
- Use phys_to_virt() instead of __va() in update_crash_elfcorehdr().
- Convert pnum_hdr_sz() to a function.
- Only assign elfcorehdr_index after kexec_add_buffer succeeds, considering
crash_handle_hotplug_event() already performs validity check on
elfcorehdr_index:
- We can safely remove the check for CPU hotplug
in arch_crash_handle_hotplug_event().
- The elfcorehdr_index's segment mem will be valid in
update_crash_elfcorehdr(), so we can safely remove the NULL check.
- Simplify the commit message.
- v1: https://lore.kernel.org/all/20260723131242.1537633-1-ruanjinjie@huawei.com/#t
Jinjie Ruan (14):
kexec: Fix CMA segment address translation with non-zero text_offset
kexec: Record allocated CMA pages to fix release size mismatch
kexec: Extract kexec_free_segment_cma() from kimage_free_cma()
arm64: kexec_file: Fix CMA page leaks in segment placement retry loops
arm64: kexec_file: Fix elf_headers memory leak in retry loop
LoongArch: kexec_file: Fix CMA page leaks in segment placement retry
loops
LoongArch: kexec_file: Fix elf_headers memory leak in retry loop
LoongArch: kexec_file: Fix a modified_cmdline leak
x86/crash: Fix massive out-of-bounds write on 32-bit Highmem
crash: Extract crash_get_memory_ranges() helper
crash: Factor out crash_find_elfcorehdr() helper
crash: Normalize the kexec_load elfcorehdr at load time
driver core: Add device_hotplug_lock_assert_held() helper
crash: Fix TOCTOU race in crash memory range collection
arch/arm64/kernel/kexec_image.c | 1 +
arch/arm64/kernel/machine_kexec_file.c | 9 +-
arch/loongarch/kernel/kexec_efi.c | 1 +
arch/loongarch/kernel/machine_kexec.c | 2 +
arch/loongarch/kernel/machine_kexec_file.c | 10 +-
arch/powerpc/kexec/crash.c | 1 +
arch/x86/kernel/crash.c | 40 +++++---
drivers/base/core.c | 5 +
include/linux/crash_core.h | 2 +
include/linux/device.h | 1 +
include/linux/kexec.h | 4 +-
kernel/crash_core.c | 114 +++++++++++++++++----
kernel/kexec.c | 4 +
kernel/kexec_core.c | 43 +++++---
kernel/kexec_file.c | 13 ++-
15 files changed, 192 insertions(+), 58 deletions(-)