* [PATCH v6 00/14] crash: Fix several bugs
@ 2026-09-21 9:04 Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 01/14] kexec: Fix CMA segment address translation with non-zero text_offset Jinjie Ruan
` (13 more replies)
0 siblings, 14 replies; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/14] kexec: Fix CMA segment address translation with non-zero text_offset
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:17 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 02/14] kexec: Record allocated CMA pages to fix release size mismatch Jinjie Ruan
` (12 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <piliu@redhat.com>
Cc: Justinien Bouron <jbouron@amazon.com>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
Cc: Breno Leitao <leitao@debian.org>
Cc: stable@vger.kernel.org
Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
kernel/kexec_core.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index dc770b9a6d05..7f7cb77f0caa 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -738,11 +738,23 @@ static struct page *kimage_alloc_page(struct kimage *image,
return page;
}
+/*
+ * Translate a boot physical address inside a CMA segment to a kernel
+ * virtual address. Architecture loaders may move segment->mem away from
+ * the CMA base (arm64 adds text_offset), so the offset must be preserved.
+ */
+static void *kimage_cma_vaddr(struct page *cma, unsigned long mem)
+{
+ unsigned long cma_base = page_to_boot_pfn(cma) << PAGE_SHIFT;
+
+ return page_address(cma) + (mem - cma_base);
+}
+
static int kimage_load_cma_segment(struct kimage *image, int idx)
{
struct kexec_segment *segment = &image->segment[idx];
struct page *cma = image->segment_cma[idx];
- char *ptr = page_address(cma);
+ char *ptr = kimage_cma_vaddr(cma, segment->mem);
size_t ubytes, mbytes;
int result = 0;
unsigned char __user *buf = NULL;
@@ -965,7 +977,7 @@ void *kimage_map_segment(struct kimage *image, int idx)
cma = image->segment_cma[idx];
if (cma)
- return page_address(cma);
+ return kimage_cma_vaddr(cma, image->segment[idx].mem);
addr = image->segment[idx].mem;
size = image->segment[idx].memsz;
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 02/14] kexec: Record allocated CMA pages to fix release size mismatch
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 01/14] kexec: Fix CMA segment address translation with non-zero text_offset Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:14 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 03/14] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
` (11 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <makb@juniper.net>
Cc: Pingfan Liu <piliu@redhat.com>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
Cc: Justinien Bouron <jbouron@amazon.com>
Cc: Li Chen <me@linux.beauty>
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 <ruanjinjie@huawei.com>
---
include/linux/kexec.h | 1 +
kernel/kexec_core.c | 7 ++++---
kernel/kexec_file.c | 13 +++++++++----
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 0af8ae4fdd08..6b1df80524bf 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -349,6 +349,7 @@ struct kimage {
unsigned long nr_segments;
struct kexec_segment segment[KEXEC_SEGMENT_MAX];
struct page *segment_cma[KEXEC_SEGMENT_MAX];
+ unsigned long segment_cma_pages[KEXEC_SEGMENT_MAX];
struct list_head control_pages;
struct list_head dest_pages;
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 7f7cb77f0caa..5493591a9e4b 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -560,14 +560,15 @@ static void kimage_free_cma(struct kimage *image)
for (i = 0; i < image->nr_segments; i++) {
struct page *cma = image->segment_cma[i];
- u32 nr_pages = image->segment[i].memsz >> PAGE_SHIFT;
+ unsigned long nr_pages = image->segment_cma_pages[i];
if (!cma)
continue;
- arch_kexec_pre_free_pages(page_address(cma), nr_pages);
- dma_release_from_contiguous(NULL, cma, nr_pages);
+ arch_kexec_pre_free_pages(page_address(cma), (unsigned int)nr_pages);
+ dma_release_from_contiguous(NULL, cma, (int)nr_pages);
image->segment_cma[i] = NULL;
+ image->segment_cma_pages[i] = 0;
}
}
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 59fb9d71e9d8..67d6df9824e6 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -670,7 +670,7 @@ static int kexec_walk_resources(struct kexec_buf *kbuf,
static int kexec_alloc_contig(struct kexec_buf *kbuf)
{
- size_t nr_pages = kbuf->memsz >> PAGE_SHIFT;
+ size_t nr_pages = PFN_DOWN(kbuf->memsz);
unsigned long mem;
struct page *p;
@@ -756,14 +756,16 @@ int kexec_locate_mem_hole(struct kexec_buf *kbuf)
*/
int kexec_add_buffer(struct kexec_buf *kbuf)
{
+ unsigned long nr_segments = kbuf->image->nr_segments;
struct kexec_segment *ksegment;
+ size_t nr_cma_pages = 0;
int ret;
/* 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)
return ret;
/* 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++;
return 0;
}
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 03/14] kexec: Extract kexec_free_segment_cma() from kimage_free_cma()
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 01/14] kexec: Fix CMA segment address translation with non-zero text_offset Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 02/14] kexec: Record allocated CMA pages to fix release size mismatch Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:13 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 04/14] arm64: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
` (10 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <ruanjinjie@huawei.com>
---
include/linux/kexec.h | 2 ++
kernel/kexec_core.c | 27 +++++++++++++++------------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 6b1df80524bf..72258d813301 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -533,6 +533,7 @@ extern bool kexec_file_dbg_print;
extern void *kimage_map_segment(struct kimage *image, int idx);
extern void kimage_unmap_segment(void *buffer);
+void kexec_free_segment_cma(struct kimage *image, unsigned long idx);
#else /* !CONFIG_KEXEC_CORE */
struct pt_regs;
struct task_struct;
@@ -544,6 +545,7 @@ static inline int kexec_crash_loaded(void) { return 0; }
static inline void *kimage_map_segment(struct kimage *image, int idx)
{ return NULL; }
static inline void kimage_unmap_segment(void *buffer) { }
+static inline void kexec_free_segment_cma(struct kimage *image, unsigned long idx) { }
#define kexec_in_progress false
#endif /* CONFIG_KEXEC_CORE */
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 5493591a9e4b..31c8228318a7 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -554,23 +554,26 @@ static void kimage_free_entry(kimage_entry_t entry)
kimage_free_pages(page);
}
-static void kimage_free_cma(struct kimage *image)
+void kexec_free_segment_cma(struct kimage *image, unsigned long idx)
{
- unsigned long i;
+ unsigned long nr_pages = image->segment_cma_pages[idx];
+ struct page *cma = image->segment_cma[idx];
- for (i = 0; i < image->nr_segments; i++) {
- struct page *cma = image->segment_cma[i];
- unsigned long nr_pages = image->segment_cma_pages[i];
+ if (!cma)
+ return;
- if (!cma)
- continue;
+ arch_kexec_pre_free_pages(page_address(cma), (unsigned int)nr_pages);
+ dma_release_from_contiguous(NULL, cma, (int)nr_pages);
+ image->segment_cma[idx] = NULL;
+ image->segment_cma_pages[idx] = 0;
+}
- arch_kexec_pre_free_pages(page_address(cma), (unsigned int)nr_pages);
- dma_release_from_contiguous(NULL, cma, (int)nr_pages);
- image->segment_cma[i] = NULL;
- image->segment_cma_pages[i] = 0;
- }
+static void kimage_free_cma(struct kimage *image)
+{
+ unsigned long i;
+ for (i = 0; i < image->nr_segments; i++)
+ kexec_free_segment_cma(image, i);
}
void kimage_free(struct kimage *image)
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 04/14] arm64: kexec_file: Fix CMA page leaks in segment placement retry loops
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (2 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 03/14] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:18 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 05/14] arm64: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
` (9 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <yeoreum.yun@arm.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: stable@vger.kernel.org
Fixes: 07d24902977e4 ("kexec: enable CMA based contiguous allocation")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/kexec_image.c | 1 +
arch/arm64/kernel/machine_kexec_file.c | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
index b70f4df15a1a..ffcb7f9075e6 100644
--- a/arch/arm64/kernel/kexec_image.c
+++ b/arch/arm64/kernel/kexec_image.c
@@ -107,6 +107,7 @@ static void *image_load(struct kimage *image,
* We couldn't find space for the other segments; erase the
* kernel segment and try the next available hole.
*/
+ kexec_free_segment_cma(image, kernel_segment_number);
image->nr_segments -= 1;
kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 854d872dfd0f..e48f29167b38 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -179,7 +179,10 @@ int load_other_segments(struct kimage *image,
return 0;
out_err:
- image->nr_segments = orig_segments;
+ while (image->nr_segments > orig_segments) {
+ kexec_free_segment_cma(image, image->nr_segments - 1);
+ image->nr_segments--;
+ }
kvfree(dtb);
return ret;
}
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 05/14] arm64: kexec_file: Fix elf_headers memory leak in retry loop
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (3 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 04/14] arm64: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:15 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 06/14] LoongArch: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
` (8 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <thuth@redhat.com>
Cc: Breno Leitao <leitao@debian.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yeoreum Yun <yeoreum.yun@arm.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: stable@vger.kernel.org
Fixes: 108aa503657e ("arm64: kexec_file: try more regions if loading segments fails")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/kernel/machine_kexec_file.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index e48f29167b38..2f750e5f4fcc 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -112,6 +112,10 @@ int load_other_segments(struct kimage *image,
vfree(headers);
goto out_err;
}
+
+ if (unlikely(image->elf_headers))
+ vfree(image->elf_headers);
+
image->elf_headers = headers;
image->elf_load_addr = kbuf.mem;
image->elf_headers_sz = headers_sz;
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 06/14] LoongArch: kexec_file: Fix CMA page leaks in segment placement retry loops
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (4 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 05/14] arm64: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:13 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 07/14] LoongArch: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
` (7 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <tangyouling@kylinos.cn>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
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 <ruanjinjie@huawei.com>
---
arch/loongarch/kernel/kexec_efi.c | 1 +
arch/loongarch/kernel/machine_kexec_file.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/kexec_efi.c b/arch/loongarch/kernel/kexec_efi.c
index 5ee78ebb1546..15fd797ff3de 100644
--- a/arch/loongarch/kernel/kexec_efi.c
+++ b/arch/loongarch/kernel/kexec_efi.c
@@ -86,6 +86,7 @@ static void *efi_kexec_load(struct kimage *image,
* We couldn't find space for the other segments; erase the
* kernel segment and try the next available hole.
*/
+ kexec_free_segment_cma(image, kernel_segment_number);
image->nr_segments -= 1;
kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
index 5412aa9f3568..62a5be102065 100644
--- a/arch/loongarch/kernel/machine_kexec_file.c
+++ b/arch/loongarch/kernel/machine_kexec_file.c
@@ -217,7 +217,11 @@ int load_other_segments(struct kimage *image,
return 0;
out_err:
- image->nr_segments = orig_segments;
+ while (image->nr_segments > orig_segments) {
+ kexec_free_segment_cma(image, image->nr_segments - 1);
+ image->nr_segments--;
+ }
+
kfree(modified_cmdline);
return ret;
}
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 07/14] LoongArch: kexec_file: Fix elf_headers memory leak in retry loop
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (5 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 06/14] LoongArch: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:14 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 08/14] LoongArch: kexec_file: Fix a modified_cmdline leak Jinjie Ruan
` (6 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <tangyouling@kylinos.cn>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
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 <ruanjinjie@huawei.com>
---
arch/loongarch/kernel/machine_kexec_file.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c
index 62a5be102065..3beb6977ecc6 100644
--- a/arch/loongarch/kernel/machine_kexec_file.c
+++ b/arch/loongarch/kernel/machine_kexec_file.c
@@ -166,6 +166,10 @@ int load_other_segments(struct kimage *image,
vfree(headers);
goto out_err;
}
+
+ if (unlikely(image->elf_headers))
+ vfree(image->elf_headers);
+
image->elf_headers = headers;
image->elf_load_addr = kbuf.mem;
image->elf_headers_sz = headers_sz;
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 08/14] LoongArch: kexec_file: Fix a modified_cmdline leak
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (6 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 07/14] LoongArch: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:15 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 09/14] x86/crash: Fix massive out-of-bounds write on 32-bit Highmem Jinjie Ruan
` (5 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <liukexin@kylinos.cn>
Cc: Youling Tang <tangyouling@kylinos.cn>
Cc: Qiang Ma <maqianga@uniontech.com>
Cc: Tianyang Zhang <zhangtianyang@loongson.cn>
Cc: George Guo <guodongtai@kylinos.cn>
Cc: stable@vger.kernel.org
Fixes: d162feec6b6e ("LoongArch: Add preparatory infrastructure for kexec_file")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/loongarch/kernel/machine_kexec.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
index 1883cae93bc3..19ccc91b6f2a 100644
--- a/arch/loongarch/kernel/machine_kexec.c
+++ b/arch/loongarch/kernel/machine_kexec.c
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <linux/of_fdt.h>
#include <linux/reboot.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
@@ -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 = (unsigned long)KEXEC_CMDLINE_ADDR;
} else {
/* Find the command line */
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 09/14] x86/crash: Fix massive out-of-bounds write on 32-bit Highmem
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (7 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 08/14] LoongArch: kexec_file: Fix a modified_cmdline leak Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 10/14] crash: Extract crash_get_memory_ranges() helper Jinjie Ruan
` (4 subsequent siblings)
13 siblings, 0 replies; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <chao.gao@intel.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Eric DeVolder <eric.devolder@oracle.com>
Cc: Hari Bathini <hbathini@linux.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
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 <ruanjinjie@huawei.com>
---
arch/x86/kernel/crash.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index e681ec9cf1dc..3c9f4fbbe7ff 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -447,9 +447,10 @@ unsigned int arch_crash_get_elfcorehdr_size(void)
*/
void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
{
- void *elfbuf = NULL, *old_elfcorehdr;
unsigned long mem, memsz;
unsigned long elfsz = 0;
+ void *elfbuf = NULL;
+ unsigned long done;
/*
* As crash_prepare_elf64_headers() has already described all
@@ -484,21 +485,20 @@ void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
/*
* Copy new elfcorehdr over the old elfcorehdr at destination.
- */
- old_elfcorehdr = kmap_local_page(pfn_to_page(mem >> PAGE_SHIFT));
- if (!old_elfcorehdr) {
- pr_err("mapping elfcorehdr segment failed\n");
- goto out;
- }
-
- /*
- * Temporarily invalidate the crash image while the
- * elfcorehdr is updated.
+ * The segment is physically contiguous but can span several pages.
+ * On 32-bit Highmem architectures, kmap_local_page() maps only a
+ * single page at a time, so copy page by page.
*/
xchg(&kexec_crash_image, NULL);
- memcpy_flushcache(old_elfcorehdr, elfbuf, elfsz);
+ for (done = 0; done < elfsz; ) {
+ size_t chunk = min_t(size_t, PAGE_SIZE, elfsz - done);
+ void *dst = kmap_local_page(pfn_to_page((mem + done) >> PAGE_SHIFT));
+
+ memcpy_flushcache(dst, elfbuf + done, chunk);
+ kunmap_local(dst);
+ done += chunk;
+ }
xchg(&kexec_crash_image, image);
- kunmap_local(old_elfcorehdr);
pr_debug("updated elfcorehdr\n");
out:
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 10/14] crash: Extract crash_get_memory_ranges() helper
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (8 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 09/14] x86/crash: Fix massive out-of-bounds write on 32-bit Highmem Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:19 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 11/14] crash: Factor out crash_find_elfcorehdr() helper Jinjie Ruan
` (3 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <ruanjinjie@huawei.com>
---
include/linux/crash_core.h | 1 +
kernel/crash_core.c | 22 +++++++++++++++++++---
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index bc087124cd78..b1c816e98143 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -62,6 +62,7 @@ extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_ma
extern int crash_prepare_headers(int need_kernel_map, void **addr,
unsigned long *sz, unsigned long *nr_mem_ranges);
extern int crash_exclude_core_ranges(struct crash_mem **cmem);
+int crash_get_memory_ranges(struct crash_mem **mem_ranges);
struct kimage;
struct kexec_segment;
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 2b36aa9fade0..406b68d2adfd 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -317,8 +317,7 @@ int crash_exclude_core_ranges(struct crash_mem **cmem)
return 0;
}
-int crash_prepare_headers(int need_kernel_map, void **addr, unsigned long *sz,
- unsigned long *nr_mem_ranges)
+int crash_get_memory_ranges(struct crash_mem **mem_ranges)
{
unsigned int max_nr_ranges;
struct crash_mem *cmem;
@@ -344,13 +343,30 @@ int crash_prepare_headers(int need_kernel_map, void **addr, unsigned long *sz,
if (ret)
goto out;
+ *mem_ranges = cmem;
+ return 0;
+
+out:
+ kvfree(cmem);
+ return ret;
+}
+
+int crash_prepare_headers(int need_kernel_map, void **addr, unsigned long *sz,
+ unsigned long *nr_mem_ranges)
+{
+ struct crash_mem *cmem = NULL;
+ int ret;
+
+ ret = crash_get_memory_ranges(&cmem);
+ if (ret)
+ return ret;
+
/* 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);
return ret;
}
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 11/14] crash: Factor out crash_find_elfcorehdr() helper
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (9 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 10/14] crash: Extract crash_get_memory_ranges() helper Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:17 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 12/14] crash: Normalize the kexec_load elfcorehdr at load time Jinjie Ruan
` (2 subsequent siblings)
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <ruanjinjie@huawei.com>
---
kernel/crash_core.c | 39 +++++++++++++++++++++++----------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 406b68d2adfd..4a990b17b66c 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -647,6 +647,28 @@ int crash_check_hotplug_support(void)
return rc;
}
+static void crash_find_elfcorehdr(struct kimage *image)
+{
+ unsigned char *ptr;
+ unsigned long mem;
+ unsigned int n;
+
+ if (image->elfcorehdr_index >= 0)
+ return;
+
+ for (n = 0; n < image->nr_segments; n++) {
+ mem = image->segment[n].mem;
+ ptr = kmap_local_page(pfn_to_page(mem >> PAGE_SHIFT));
+ if (!ptr)
+ continue;
+
+ /* The segment containing elfcorehdr */
+ if (memcmp(ptr, ELFMAG, SELFMAG) == 0)
+ image->elfcorehdr_index = (int)n;
+ kunmap_local(ptr);
+ }
+}
+
/*
* To accurately reflect hot un/plug changes of CPU and Memory resources
* (including onling and offlining of those resources), the relevant
@@ -702,22 +724,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
* is allocated. Find the segment containing the elfcorehdr,
* if not already found.
*/
- if (image->elfcorehdr_index < 0) {
- unsigned long mem;
- unsigned char *ptr;
- unsigned int n;
-
- for (n = 0; n < image->nr_segments; n++) {
- mem = image->segment[n].mem;
- ptr = kmap_local_page(pfn_to_page(mem >> PAGE_SHIFT));
- if (ptr) {
- /* The segment containing elfcorehdr */
- if (memcmp(ptr, ELFMAG, SELFMAG) == 0)
- image->elfcorehdr_index = (int)n;
- kunmap_local(ptr);
- }
- }
- }
+ crash_find_elfcorehdr(image);
if (image->elfcorehdr_index < 0) {
pr_err("unable to locate elfcorehdr segment");
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 12/14] crash: Normalize the kexec_load elfcorehdr at load time
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (10 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 11/14] crash: Factor out crash_find_elfcorehdr() helper Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:19 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 13/14] driver core: Add device_hotplug_lock_assert_held() helper Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 14/14] crash: Fix TOCTOU race in crash memory range collection Jinjie Ruan
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <sourabhjain@linux.ibm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
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(-)
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index 775895f31037..8ede33740fc0 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -638,6 +638,7 @@ void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
struct memory_notify *mn;
switch (image->hp_action) {
+ case KEXEC_CRASH_HP_NONE:
case KEXEC_CRASH_HP_REMOVE_CPU:
return;
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 3c9f4fbbe7ff..f34fa8dba028 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -457,9 +457,8 @@ void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
* possible CPUs, there is no need to update the elfcorehdr
* for additional CPU changes.
*/
- if ((image->file_mode || image->elfcorehdr_updated) &&
- ((image->hp_action == KEXEC_CRASH_HP_ADD_CPU) ||
- (image->hp_action == KEXEC_CRASH_HP_REMOVE_CPU)))
+ if (image->hp_action == KEXEC_CRASH_HP_ADD_CPU ||
+ image->hp_action == KEXEC_CRASH_HP_REMOVE_CPU)
return;
/*
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index b1c816e98143..a740757dff35 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -39,6 +39,7 @@ static inline void arch_crash_handle_hotplug_event(struct kimage *image, void *a
#endif
int crash_check_hotplug_support(void);
+void crash_hotplug_prepare_elfcorehdr(struct kimage *image);
#ifndef arch_crash_hotplug_support
static inline int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 72258d813301..f1f218e46db0 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -404,7 +404,6 @@ struct kimage {
#ifdef CONFIG_CRASH_HOTPLUG
int hp_action;
int elfcorehdr_index;
- bool elfcorehdr_updated;
#endif
#ifdef CONFIG_IMA_KEXEC
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 4a990b17b66c..b638ad0e5ba2 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -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();
}
+void crash_hotplug_prepare_elfcorehdr(struct kimage *image)
+{
+ if (!image || !image->hotplug_support || image->file_mode)
+ return;
+
+ crash_find_elfcorehdr(image);
+ if (image->elfcorehdr_index < 0)
+ return;
+
+ /*
+ * kexec_load() images are not normalized at load, so do it here while
+ * the lock is still free to take. hp_action is KEXEC_CRASH_HP_NONE,
+ * which the arch handler treats as "just rebuild the elfcorehdr".
+ */
+ lock_device_hotplug();
+ arch_crash_handle_hotplug_event(image, NULL);
+ unlock_device_hotplug();
+}
+
static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *arg)
{
switch (val) {
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 90756dc6339b..ea9ba00bc786 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -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);
+#endif
out:
#ifdef CONFIG_CRASH_DUMP
if ((flags & KEXEC_ON_CRASH) && kexec_crash_image)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index 31c8228318a7..c36a5e8b400e 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -251,7 +251,6 @@ struct kimage *do_kimage_alloc_init(void)
#ifdef CONFIG_CRASH_HOTPLUG
image->hp_action = KEXEC_CRASH_HP_NONE;
image->elfcorehdr_index = -1;
- image->elfcorehdr_updated = false;
#endif
return image;
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 13/14] driver core: Add device_hotplug_lock_assert_held() helper
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (11 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 12/14] crash: Normalize the kexec_load elfcorehdr at load time Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:18 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 14/14] crash: Fix TOCTOU race in crash memory range collection Jinjie Ruan
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <ruanjinjie@huawei.com>
---
drivers/base/core.c | 5 +++++
include/linux/device.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4c0c373998a1..c04adc457a96 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2420,6 +2420,11 @@ void unlock_device_hotplug(void)
mutex_unlock(&device_hotplug_lock);
}
+void device_hotplug_lock_assert_held(void)
+{
+ lockdep_assert_held(&device_hotplug_lock);
+}
+
int lock_device_hotplug_sysfs(void)
{
if (mutex_trylock(&device_hotplug_lock))
diff --git a/include/linux/device.h b/include/linux/device.h
index aee79fd6b32b..9cca8c8bd372 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1261,6 +1261,7 @@ do { \
void lock_device_hotplug(void);
void unlock_device_hotplug(void);
int lock_device_hotplug_sysfs(void);
+void device_hotplug_lock_assert_held(void);
int device_offline(struct device *dev);
int device_online(struct device *dev);
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 14/14] crash: Fix TOCTOU race in crash memory range collection
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
` (12 preceding siblings ...)
2026-09-21 9:04 ` [PATCH v6 13/14] driver core: Add device_hotplug_lock_assert_held() helper Jinjie Ruan
@ 2026-09-21 9:04 ` Jinjie Ruan
2026-09-21 9:25 ` sashiko-bot
13 siblings, 1 reply; 28+ messages in thread
From: Jinjie Ruan @ 2026-09-21 9:04 UTC (permalink / raw)
To: catalin.marinas, will, mark.rutland, chenhuacai, kernel, maddy,
mpe, npiggin, chleroy, ritesh.list, sshegde, tglx, mingo, bp,
dave.hansen, hpa, gregkh, rafael, dakr, akpm, baoquan.he, rppt,
pasha.tatashin, pratyush, ruirui.yang, leitao, yeoreum.yun,
sourabhjain, robh, coxu, kees, tangyouling, liukexin,
zhangtianyang, guodongtai, maqianga, chao.gao, kai.huang,
vishal.l.verma, seanjc, piliu, thuth, jbouron, me, mclapinski,
graf, bgwin, hbathini, eric.devolder, takahiro.akashi,
james.morse, palmer, x86, linux-arm-kernel, linux-kernel,
loongarch, linuxppc-dev, driver-core, kexec
Cc: ruanjinjie
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 <takahiro.akashi@linaro.org>
Cc: Will Deacon <will@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Palmer Dabbelt <palmer@rivosinc.com>
Cc: Youling Tang <tangyouling@kylinos.cn>
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 <ruanjinjie@huawei.com>
---
arch/x86/kernel/crash.c | 9 ++++++++-
include/linux/crash_core.h | 2 +-
kernel/crash_core.c | 35 ++++++++++++++++++++++++++++++++++-
3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index f34fa8dba028..7fa139725514 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -447,6 +447,7 @@ unsigned int arch_crash_get_elfcorehdr_size(void)
*/
void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
{
+ struct crash_mem *cmem = NULL;
unsigned long mem, memsz;
unsigned long elfsz = 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");
+ goto out;
+ }
+
/*
* Create the new elfcorehdr reflecting the changes to CPU and/or
* memory resources.
*/
- 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");
goto out;
}
@@ -501,6 +507,7 @@ void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
pr_debug("updated elfcorehdr\n");
out:
+ kvfree(cmem);
vfree(elfbuf);
}
#endif
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
index a740757dff35..1296a9b29974 100644
--- a/include/linux/crash_core.h
+++ b/include/linux/crash_core.h
@@ -63,7 +63,7 @@ extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_ma
extern int crash_prepare_headers(int need_kernel_map, void **addr,
unsigned long *sz, unsigned long *nr_mem_ranges);
extern int crash_exclude_core_ranges(struct crash_mem **cmem);
-int crash_get_memory_ranges(struct crash_mem **mem_ranges);
+int crash_get_memory_ranges_nolock(struct crash_mem **mem_ranges);
struct kimage;
struct kexec_segment;
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index b638ad0e5ba2..43b21de1d64a 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -7,6 +7,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/buildid.h>
+#include <linux/device.h>
#include <linux/init.h>
#include <linux/utsname.h>
#include <linux/vmalloc.h>
@@ -317,12 +318,33 @@ int crash_exclude_core_ranges(struct crash_mem **cmem)
return 0;
}
-int crash_get_memory_ranges(struct crash_mem **mem_ranges)
+/**
+ * crash_get_memory_ranges_nolock - Collect crash kernel memory ranges
+ * @mem_ranges: Output parameter for the allocated crash_mem structure
+ *
+ * Gathers the system memory ranges to be included in the crash kernel's
+ * ELF core header, excluding the crashkernel reserved region and other
+ * architecture-specific areas.
+ *
+ * Context: Caller must hold device_hotplug_lock.
+ *
+ * Return: 0 on success, in which case *@mem_ranges points to a newly
+ * allocated struct crash_mem that the caller must free with kvfree().
+ * Returns a negative error code on failure.
+ */
+int crash_get_memory_ranges_nolock(struct crash_mem **mem_ranges)
{
unsigned int max_nr_ranges;
struct crash_mem *cmem;
int ret;
+ /*
+ * Callers must serialize against memory hotplug by holding
+ * device_hotplug_lock, otherwise the memblock iteration below can
+ * race with memblock_double_array() and read freed memory.
+ */
+ device_hotplug_lock_assert_held();
+
max_nr_ranges = arch_get_system_nr_ranges();
if (!max_nr_ranges)
return -ENOMEM;
@@ -351,6 +373,17 @@ int crash_get_memory_ranges(struct crash_mem **mem_ranges)
return ret;
}
+static int crash_get_memory_ranges(struct crash_mem **mem_ranges)
+{
+ int ret;
+
+ lock_device_hotplug();
+ ret = crash_get_memory_ranges_nolock(mem_ranges);
+ unlock_device_hotplug();
+
+ return ret;
+}
+
int crash_prepare_headers(int need_kernel_map, void **addr, unsigned long *sz,
unsigned long *nr_mem_ranges)
{
--
2.34.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 06/14] LoongArch: kexec_file: Fix CMA page leaks in segment placement retry loops
2026-09-21 9:04 ` [PATCH v6 06/14] LoongArch: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
@ 2026-09-21 9:13 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:13 UTC (permalink / raw)
To: npiggin, ritesh.list, sshegde, piliu, guodongtai, will,
eric.devolder, vishal.l.verma, maddy, mpe, bp, kai.huang,
chao.gao, robh, seanjc, dakr, pasha.tatashin, kernel, rppt,
zhangtianyang, hbathini, baoquan.he, james.morse, thuth,
loongarch, yeoreum.yun, coxu, chenhuacai, akpm, kees, jbouron,
pratyush, me, mark.rutland, chleroy, linuxppc-dev, sourabhjain,
linux-arm-kernel, graf, gregkh, liukexin, x86, mclapinski,
ruirui.yang, takahiro.akashi, hpa
Cc: ruanjinjie, kexec
> 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 <tangyouling@kylinos.cn>
> Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
> Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=6
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 03/14] kexec: Extract kexec_free_segment_cma() from kimage_free_cma()
2026-09-21 9:04 ` [PATCH v6 03/14] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
@ 2026-09-21 9:13 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:13 UTC (permalink / raw)
To: dakr, hbathini, npiggin, maqianga, vishal.l.verma, baoquan.he,
piliu, ruirui.yang, linuxppc-dev, pratyush, maddy, bgwin, robh,
Jinjie Ruan, mingo, me, linux-kernel, catalin.marinas,
takahiro.akashi, james.morse, yeoreum.yun, mark.rutland,
eric.devolder, coxu, chao.gao, ritesh.list, kees, liukexin,
leitao, sourabhjain, tglx, kernel, bp, loongarch, rafael, seanjc,
dave.hansen, palmer, pasha.tatashin, rppt, driver-core,
kai.huang, graf, jbouron, guodongtai, thuth, chenhuacai,
linux-arm-kernel, hpa, gregkh, akpm, sshegde, will, x86, mpe,
chleroy, mclapinski, tangyouling, zha
Cc: kexec, ruanjinjie
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=3
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 07/14] LoongArch: kexec_file: Fix elf_headers memory leak in retry loop
2026-09-21 9:04 ` [PATCH v6 07/14] LoongArch: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
@ 2026-09-21 9:14 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:14 UTC (permalink / raw)
To: james.morse, thuth, me, linux-arm-kernel, linux-kernel,
vishal.l.verma, pasha.tatashin, sourabhjain, baoquan.he,
chao.gao, akpm, kai.huang, mingo, kernel, seanjc, piliu,
mclapinski, palmer, linuxppc-dev, bp, mpe, driver-core, kees,
gregkh, hbathini, chleroy, leitao, will, x86, dakr, guodongtai,
hpa, maddy, takahiro.akashi, catalin.marinas, sshegde, loongarch,
zhangtianyang, Jinjie Ruan, maqianga, mark.rutland, chenhuacai,
tangyouling, eric.devolder, tglx, ruirui.yang, graf, bgwin,
npiggin, pratyush, rafael, yeoreum.yun, coxu, liukexin,
dave.hansen, ritesh.list, rppt, jbouron, robh
Cc: kexec, ruanjinjie
> 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 <tangyouling@kylinos.cn>
> Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
> Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=7
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 02/14] kexec: Record allocated CMA pages to fix release size mismatch
2026-09-21 9:04 ` [PATCH v6 02/14] kexec: Record allocated CMA pages to fix release size mismatch Jinjie Ruan
@ 2026-09-21 9:14 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:14 UTC (permalink / raw)
To: rafael, eric.devolder, chao.gao, ritesh.list, mark.rutland,
linux-kernel, leitao, sshegde, kees, robh, loongarch, chleroy,
liukexin, x86, hbathini, Jinjie Ruan, maddy, guodongtai,
mclapinski, gregkh, me, pratyush, palmer, hpa, bp,
vishal.l.verma, bgwin, takahiro.akashi, chenhuacai, seanjc,
dave.hansen, tglx, yeoreum.yun, akpm, sourabhjain, driver-core,
mpe, will, tangyouling, dakr, baoquan.he, graf, kai.huang,
pasha.tatashin, jbouron, mingo, ruirui.yang, rppt, kernel, thuth,
coxu, catalin.marinas, npiggin, linux-arm-kernel, maqianga,
piliu, linuxppc-dev, james.morse, zhangtianyang
Cc: kexec, ruanjinjie
> 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 <makb@juniper.net>
> Cc: Pingfan Liu <piliu@redhat.com>
> Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
> Cc: Justinien Bouron <jbouron@amazon.com>
> Cc: Li Chen <me@linux.beauty>
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=2
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 05/14] arm64: kexec_file: Fix elf_headers memory leak in retry loop
2026-09-21 9:04 ` [PATCH v6 05/14] arm64: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
@ 2026-09-21 9:15 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:15 UTC (permalink / raw)
To: kees, eric.devolder, yeoreum.yun, driver-core, hbathini, me,
rppt, jbouron, hpa, linux-arm-kernel, dakr, maddy, tangyouling,
will, mark.rutland, dave.hansen, sourabhjain, catalin.marinas,
leitao, vishal.l.verma, bp, guodongtai, zhangtianyang, loongarch,
linuxppc-dev, rafael, kai.huang, mclapinski, piliu, sshegde,
thuth, Jinjie Ruan, coxu, linux-kernel, x86, chenhuacai,
chao.gao, ruirui.yang, bgwin, takahiro.akashi, palmer, seanjc,
chleroy, liukexin, pratyush, kernel, james.morse, maqianga,
npiggin, baoquan.he, gregkh, akpm, ritesh.list, graf, tglx,
mingo, robh, mpe, pasha.tatashin
Cc: ruanjinjie, kexec
> 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 <thuth@redhat.com>
> Cc: Breno Leitao <leitao@debian.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Yeoreum Yun <yeoreum.yun@arm.com>
> Cc: Baoquan He <bhe@redhat.com>
> Cc: stable@vger.kernel.org
> Fixes: 108aa503657e ("arm64: kexec_file: try more regions if loading segments fails")
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=5
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 08/14] LoongArch: kexec_file: Fix a modified_cmdline leak
2026-09-21 9:04 ` [PATCH v6 08/14] LoongArch: kexec_file: Fix a modified_cmdline leak Jinjie Ruan
@ 2026-09-21 9:15 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:15 UTC (permalink / raw)
To: maqianga, dakr, kees, mingo, seanjc, gregkh, mpe, driver-core,
palmer, chleroy, coxu, akpm, piliu, linux-kernel, loongarch,
mclapinski, robh, maddy, hpa, ruirui.yang, bgwin, leitao,
catalin.marinas, jbouron, npiggin, guodongtai, kai.huang,
sourabhjain, bp, baoquan.he, pratyush, pasha.tatashin,
chenhuacai, zhangtianyang, ritesh.list, vishal.l.verma, thuth,
x86, linuxppc-dev, hbathini, tglx, yeoreum.yun, sshegde, rppt,
will, Jinjie Ruan, rafael, kernel, me, james.morse,
linux-arm-kernel, dave.hansen, liukexin, graf, mark.rutland,
chao.gao, takahiro.akashi, eric.devolder, tangyouling
Cc: ruanjinjie, kexec
> 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 <liukexin@kylinos.cn>
> Cc: Youling Tang <tangyouling@kylinos.cn>
> Cc: Qiang Ma <maqianga@uniontech.com>
> Cc: Tianyang Zhang <zhangtianyang@loongson.cn>
> Cc: George Guo <guodongtai@kylinos.cn>
> Cc: stable@vger.kernel.org
> Fixes: d162feec6b6e ("LoongArch: Add preparatory infrastructure for kexec_file")
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=8
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 11/14] crash: Factor out crash_find_elfcorehdr() helper
2026-09-21 9:04 ` [PATCH v6 11/14] crash: Factor out crash_find_elfcorehdr() helper Jinjie Ruan
@ 2026-09-21 9:17 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:17 UTC (permalink / raw)
To: dave.hansen, chao.gao, driver-core, tglx, leitao, chenhuacai,
piliu, seanjc, chleroy, gregkh, kees, zhangtianyang, mclapinski,
will, kai.huang, Jinjie Ruan, eric.devolder, akpm, pratyush,
loongarch, x86, mpe, robh, rafael, pasha.tatashin, ruirui.yang,
jbouron, tangyouling, vishal.l.verma, npiggin, yeoreum.yun,
mark.rutland, takahiro.akashi, mingo, liukexin, kernel, maqianga,
sourabhjain, linux-kernel, sshegde, james.morse, linuxppc-dev,
hpa, hbathini, linux-arm-kernel, thuth, graf, dakr, bgwin, me,
guodongtai, palmer, bp, catalin.marinas, coxu, rppt, maddy,
baoquan.he, ritesh.list
Cc: ruanjinjie, kexec
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=11
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 01/14] kexec: Fix CMA segment address translation with non-zero text_offset
2026-09-21 9:04 ` [PATCH v6 01/14] kexec: Fix CMA segment address translation with non-zero text_offset Jinjie Ruan
@ 2026-09-21 9:17 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:17 UTC (permalink / raw)
To: sourabhjain, rppt, dave.hansen, mpe, bgwin, kees, zhangtianyang,
chenhuacai, eric.devolder, akpm, chleroy, sshegde, chao.gao,
jbouron, mclapinski, tangyouling, mark.rutland, seanjc, palmer,
leitao, yeoreum.yun, x86, ritesh.list, maqianga, kernel, mingo,
takahiro.akashi, james.morse, linux-arm-kernel, bp, robh,
pasha.tatashin, driver-core, linuxppc-dev, hpa, pratyush,
guodongtai, graf, catalin.marinas, kai.huang, Jinjie Ruan,
npiggin, vishal.l.verma, baoquan.he, linux-kernel, loongarch, me,
coxu, hbathini, will, maddy, liukexin, piliu, ruirui.yang, tglx,
dakr, thuth, rafael, gregkh
Cc: kexec, ruanjinjie
> 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 <sourabhjain@linux.ibm.com>
> Cc: Breno Leitao <leitao@debian.org>
> Cc: stable@vger.kernel.org
> Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=1
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 13/14] driver core: Add device_hotplug_lock_assert_held() helper
2026-09-21 9:04 ` [PATCH v6 13/14] driver core: Add device_hotplug_lock_assert_held() helper Jinjie Ruan
@ 2026-09-21 9:18 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:18 UTC (permalink / raw)
To: bp, kernel, graf, npiggin, hpa, rafael, hbathini, leitao,
takahiro.akashi, palmer, akpm, me, sshegde, sourabhjain,
kai.huang, x86, ritesh.list, pasha.tatashin, coxu, linuxppc-dev,
baoquan.he, mark.rutland, linux-kernel, piliu, zhangtianyang,
will, chleroy, chao.gao, loongarch, yeoreum.yun, tangyouling,
pratyush, rppt, mingo, seanjc, bgwin, catalin.marinas, liukexin,
driver-core, guodongtai, mclapinski, james.morse, Jinjie Ruan,
robh, vishal.l.verma, kees, linux-arm-kernel, dave.hansen,
jbouron, thuth, chenhuacai, tglx, maddy, dakr, ruirui.yang,
eric.devolder, maqianga, gregkh, mpe
Cc: kexec, ruanjinjie
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=13
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 04/14] arm64: kexec_file: Fix CMA page leaks in segment placement retry loops
2026-09-21 9:04 ` [PATCH v6 04/14] arm64: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
@ 2026-09-21 9:18 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:18 UTC (permalink / raw)
To: guodongtai, linux-arm-kernel, yeoreum.yun, mclapinski,
ruirui.yang, eric.devolder, hbathini, kernel, piliu, thuth,
ritesh.list, tglx, mpe, x86, takahiro.akashi, akpm, chenhuacai,
rppt, catalin.marinas, bp, pasha.tatashin, maddy, driver-core,
dave.hansen, vishal.l.verma, bgwin, npiggin, chleroy,
Jinjie Ruan, mark.rutland, leitao, james.morse, maqianga, rafael,
sshegde, jbouron, me, pratyush, palmer, linux-kernel, baoquan.he,
gregkh, mingo, zhangtianyang, hpa, chao.gao, kai.huang,
tangyouling, coxu, dakr, kees, graf, linuxppc-dev, robh, will,
sourabhjain, liukexin, seanjc, loongarch
Cc: kexec, ruanjinjie
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 <ruanjinjie@huawei.com>
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.
> diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
> index b70f4df15a1ae..ffcb7f9075e62 100644
> --- a/arch/arm64/kernel/kexec_image.c
> +++ b/arch/arm64/kernel/kexec_image.c
> @@ -107,6 +107,7 @@ static void *image_load(struct kimage *image,
> * We couldn't find space for the other segments; erase the
> * kernel segment and try the next available hole.
> */
> + kexec_free_segment_cma(image, kernel_segment_number);
> image->nr_segments -= 1;
> kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
> kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
[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
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 10/14] crash: Extract crash_get_memory_ranges() helper
2026-09-21 9:04 ` [PATCH v6 10/14] crash: Extract crash_get_memory_ranges() helper Jinjie Ruan
@ 2026-09-21 9:19 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:19 UTC (permalink / raw)
To: catalin.marinas, hpa, bgwin, mpe, vishal.l.verma,
takahiro.akashi, chleroy, baoquan.he, yeoreum.yun, maddy,
sshegde, ruirui.yang, rafael, coxu, loongarch, leitao, palmer,
robh, rppt, jbouron, kees, james.morse, Jinjie Ruan,
mark.rutland, npiggin, will, sourabhjain, ritesh.list,
pasha.tatashin, linuxppc-dev, akpm, bp, thuth, chenhuacai, mingo,
linux-arm-kernel, linux-kernel, piliu, driver-core, graf, me,
dave.hansen, gregkh, mclapinski, seanjc, maqianga, chao.gao,
guodongtai, tangyouling, liukexin, dakr, x86, hbathini,
zhangtianyang, tglx, kernel, pratyush, eric.devolder, kai.huang
Cc: kexec, ruanjinjie
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=10
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 12/14] crash: Normalize the kexec_load elfcorehdr at load time
2026-09-21 9:04 ` [PATCH v6 12/14] crash: Normalize the kexec_load elfcorehdr at load time Jinjie Ruan
@ 2026-09-21 9:19 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:19 UTC (permalink / raw)
To: zhangtianyang, chleroy, eric.devolder, linux-kernel, driver-core,
dakr, guodongtai, hpa, kernel, chao.gao, pasha.tatashin, npiggin,
coxu, liukexin, seanjc, bgwin, rppt, bp, kai.huang, sshegde,
kees, mpe, tglx, jbouron, yeoreum.yun, Jinjie Ruan, maddy,
gregkh, will, pratyush, akpm, robh, tangyouling, piliu, hbathini,
mark.rutland, chenhuacai, me, mclapinski, dave.hansen,
ritesh.list, x86, linux-arm-kernel, leitao, palmer, maqianga,
james.morse, takahiro.akashi, linuxppc-dev, loongarch,
vishal.l.verma, catalin.marinas, graf, sourabhjain, mingo,
ruirui.yang, rafael, baoquan.he, thuth
Cc: kexec, ruanjinjie
> 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 <sourabhjain@linux.ibm.com>
> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=12
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v6 14/14] crash: Fix TOCTOU race in crash memory range collection
2026-09-21 9:04 ` [PATCH v6 14/14] crash: Fix TOCTOU race in crash memory range collection Jinjie Ruan
@ 2026-09-21 9:25 ` sashiko-bot
0 siblings, 0 replies; 28+ messages in thread
From: sashiko-bot @ 2026-09-21 9:25 UTC (permalink / raw)
To: kees, piliu, npiggin, mpe, me, bgwin, mingo, x86, baoquan.he,
guodongtai, leitao, driver-core, coxu, pratyush, Jinjie Ruan,
will, dakr, sourabhjain, maqianga, gregkh, sshegde, liukexin,
kernel, thuth, hbathini, linux-kernel, mclapinski, tglx,
kai.huang, linuxppc-dev, robh, seanjc, james.morse, palmer,
chleroy, yeoreum.yun, loongarch, jbouron, catalin.marinas,
ritesh.list, akpm, rppt, eric.devolder, chenhuacai,
vishal.l.verma, dave.hansen, chao.gao, pasha.tatashin, bp,
mark.rutland, takahiro.akashi, zhangtianyang, rafael,
tangyouling, graf, ruirui.yang, hpa, linux-arm-kernel
Cc: kexec, ruanjinjie
> 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 <ruanjinjie@huawei.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260921090450.807575-1-ruanjinjie@huawei.com?part=14
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2026-09-21 9:25 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-21 9:04 [PATCH v6 00/14] crash: Fix several bugs Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 01/14] kexec: Fix CMA segment address translation with non-zero text_offset Jinjie Ruan
2026-09-21 9:17 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 02/14] kexec: Record allocated CMA pages to fix release size mismatch Jinjie Ruan
2026-09-21 9:14 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 03/14] kexec: Extract kexec_free_segment_cma() from kimage_free_cma() Jinjie Ruan
2026-09-21 9:13 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 04/14] arm64: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
2026-09-21 9:18 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 05/14] arm64: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
2026-09-21 9:15 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 06/14] LoongArch: kexec_file: Fix CMA page leaks in segment placement retry loops Jinjie Ruan
2026-09-21 9:13 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 07/14] LoongArch: kexec_file: Fix elf_headers memory leak in retry loop Jinjie Ruan
2026-09-21 9:14 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 08/14] LoongArch: kexec_file: Fix a modified_cmdline leak Jinjie Ruan
2026-09-21 9:15 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 09/14] x86/crash: Fix massive out-of-bounds write on 32-bit Highmem Jinjie Ruan
2026-09-21 9:04 ` [PATCH v6 10/14] crash: Extract crash_get_memory_ranges() helper Jinjie Ruan
2026-09-21 9:19 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 11/14] crash: Factor out crash_find_elfcorehdr() helper Jinjie Ruan
2026-09-21 9:17 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 12/14] crash: Normalize the kexec_load elfcorehdr at load time Jinjie Ruan
2026-09-21 9:19 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 13/14] driver core: Add device_hotplug_lock_assert_held() helper Jinjie Ruan
2026-09-21 9:18 ` sashiko-bot
2026-09-21 9:04 ` [PATCH v6 14/14] crash: Fix TOCTOU race in crash memory range collection Jinjie Ruan
2026-09-21 9:25 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®