[PATCH v3 2/9] riscv: kexec: Bound FDT search by source buffer size, not destination
From: fangyu . yu
Date: Thu Jun 04 2026 - 09:29:42 EST
From: Fangyu Yu <fangyu.yu@xxxxxxxxxxxxxxxxx>
The FDT search loop in machine_kexec_prepare() reads sizeof(fdt) bytes
from segment[i].buf to identify the device tree, but it gates the read
on segment[i].memsz, which is the destination size in the next kernel.
kexec allows bufsz < memsz (the loaded image is zero-padded at the
destination), so a caller can craft a segment with bufsz=10 and
memsz=1MB:
if (image->segment[i].memsz <= sizeof(fdt)) /* 1MB > 40, OK */
continue;
memcpy(&fdt, image->segment[i].buf, sizeof(fdt)); /* reads 40
from a 10-byte
kbuf */
For kexec_file_load (image->file_mode), the read walks 30 bytes past
the kernel-allocated kbuf. In the worst case the trailing bytes fall
in an unmapped guard page and the read faults the kernel; in the
common case the read returns garbage which fdt_check_header() rejects
and the loop continues. The plain kexec_load path is shielded by
copy_from_user(), which validates the read against the user mapping.
Replace the memsz check with the bufsz check, which is the right
bound for the read site.
Fixes: fba8a8674f68 ("RISC-V: Add kexec support")
Signed-off-by: Fangyu Yu <fangyu.yu@xxxxxxxxxxxxxxxxx>
---
arch/riscv/kernel/machine_kexec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index ea6794c9f4c2..e6e179cffc44 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -38,7 +38,7 @@ machine_kexec_prepare(struct kimage *image)
/* Find the Flattened Device Tree and save its physical address */
for (i = 0; i < image->nr_segments; i++) {
- if (image->segment[i].memsz <= sizeof(fdt))
+ if (image->segment[i].bufsz < sizeof(fdt))
continue;
if (image->file_mode)
--
2.50.1