[PATCH] x86/kexec: bound bzImage64 setup header copy

Pengpeng Hou pengpeng at iscas.ac.cn
Sat Mar 21 20:19:24 PDT 2026


`bzImage64_load()` computes the size of the setup header from the image
header bytes and copies that amount into `params->hdr` without first
verifying that the derived size fits the destination `setup_header`.
Current in-tree images line up with the expected header length, but the
loader still trusts the image-derived byte and will happily copy a
larger header area from a malformed bzImage.

Reject setup headers larger than `struct setup_header` before copying
them into `boot_params`.

Signed-off-by: Pengpeng Hou <pengpeng at iscas.ac.cn>
---
 arch/x86/kernel/kexec-bzimage64.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 5630c7dca1f3..ac31bf092292 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -587,16 +587,20 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
 		kbuf.bufsz += sizeof(struct setup_data) +
 			      sizeof(struct kho_data);
 
+	/* Copy setup header onto bootparams. Documentation/arch/x86/boot.rst */
+	setup_header_size = 0x0202 + (unsigned char)kernel[0x0201] -
+			    setup_hdr_offset;
+	if (setup_header_size > sizeof(struct setup_header)) {
+		pr_err("bzImage setup header too large\n");
+		return ERR_PTR(-ENOEXEC);
+	}
+
 	params = kvzalloc(kbuf.bufsz, GFP_KERNEL);
 	if (!params)
 		return ERR_PTR(-ENOMEM);
 	efi_map_offset = params_cmdline_sz;
 	efi_setup_data_offset = efi_map_offset + ALIGN(efi_map_sz, 16);
 
-	/* Copy setup header onto bootparams. Documentation/arch/x86/boot.rst */
-	setup_header_size = 0x0202 + kernel[0x0201] - setup_hdr_offset;
-
-	/* Is there a limit on setup header size? */
 	memcpy(&params->hdr, (kernel + setup_hdr_offset), setup_header_size);
 
 	kbuf.buffer = params;
-- 
2.50.1 (Apple Git-155)




More information about the kexec mailing list