diff mbox series

[RFC] efi: Put Linux specific magic number in the DOS header

Message ID 20221109141611.2788009-1-ardb@kernel.org
State Superseded
Headers show
Series [RFC] efi: Put Linux specific magic number in the DOS header | expand

Commit Message

Ard Biesheuvel Nov. 9, 2022, 2:16 p.m. UTC
GRUB currently relies on the magic number in the image header of ARM and
arm64 EFI kernel images to decide whether or not the image in question
is a bootable kernel.

However, the purpose of the magic number is to identify the image as one
that implements the bare metal boot protocol, and so GRUB, which only
does EFI boot, can only boot images that could potentially be booted in
a non-EFI manner as well.

This is problematic for the new zboot decompressor image format, as it
can only boot in EFI mode, and must therefore not use the bare metal
boot magic number in its header.

For this reason, the strict magic number was dropped from GRUB, to
permit essentially any kind of EFI executable to be booted via the
'linux' command, blurring the line between the linux loader and the
chainloader.

So let's use the same field in the DOS header that RISC-V and arm64
already use for their 'bare metal' magic numbers to store a 'generic
Linux kernel' magic number, which can be used to identify bootable
kernel images in PE format which don't necessarily implement a bare
metal boot protocol in the same binary.

Let's set the generic magic number for x86 images as well: existing
bootloaders already have their own methods to identify x86 Linux images
that can be booted in a non-EFI manner, and having the magic number in
place there will ease any future transitions in loader implementations
to merge the x86 and non-x86 EFI boot paths.

Note that 32-bit ARM already uses the same location in the header for a
different purpose, but the ARM support is already widely implemented and
the EFI zboot decompressor is not available on ARM anyway, so we just
disregard it here.

Cc: Huacai Chen <chenhuacai@kernel.org> 
Cc: Atish Patra <atishp@rivosinc.com>
Cc: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Cc: Daniel Kiper <daniel.kiper@oracle.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
The idea is that, with this in place, the existing arm64 support in GRUB
can be made generic, with the arm64 variant of the arch image header
typedef being made generic as well.

Any code that attempts to identify EFI images as kernel images should
check for the arm64, RISC-V and generic values, and if the latter, look
at the PE machine type if it wants to know the architecture.

 arch/loongarch/kernel/head.S                | 3 ++-
 arch/x86/boot/header.S                      | 3 ++-
 drivers/firmware/efi/libstub/zboot-header.S | 3 ++-
 include/linux/pe.h                          | 7 +++++++
 4 files changed, 13 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index 97425779ce9f3499..e1deea93aaafa069 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -25,7 +25,8 @@  _head:
 	.dword	kernel_entry		/* Kernel entry point */
 	.dword	_end - _text		/* Kernel image effective size */
 	.quad	0			/* Kernel image load offset from start of RAM */
-	.org	0x3c			/* 0x20 ~ 0x3b reserved */
+	.org	0x38			/* 0x20 ~ 0x38 reserved */
+	.long	LINUX_PE_MAGIC
 	.long	pe_header - _head	/* Offset to the PE header */
 
 pe_header:
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index d31982509654dcb1..9338c68e7413d6e6 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -80,10 +80,11 @@  bs_die:
 	ljmp	$0xf000,$0xfff0
 
 #ifdef CONFIG_EFI_STUB
-	.org	0x3c
+	.org	0x38
 	#
 	# Offset to the PE header.
 	#
+	.long	LINUX_PE_MAGIC
 	.long	pe_header
 #endif /* CONFIG_EFI_STUB */
 
diff --git a/drivers/firmware/efi/libstub/zboot-header.S b/drivers/firmware/efi/libstub/zboot-header.S
index 9e6fe061ab07a008..97c2637337d79913 100644
--- a/drivers/firmware/efi/libstub/zboot-header.S
+++ b/drivers/firmware/efi/libstub/zboot-header.S
@@ -20,7 +20,8 @@  __efistub_efi_zboot_header:
 	.long		__efistub__gzdata_size - ZBOOT_SIZE_LEN	// payload size
 	.long		0, 0					// reserved
 	.asciz		COMP_TYPE				// compression type
-	.org		.Ldoshdr + 0x3c
+	.org		.Ldoshdr + 0x38
+	.long		LINUX_PE_MAGIC
 	.long		.Lpehdr - .Ldoshdr			// PE header offset
 
 .Lpehdr:
diff --git a/include/linux/pe.h b/include/linux/pe.h
index 1d3836ef9d92dcd8..fa176c24167c301c 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -31,6 +31,13 @@ 
 #define LINUX_EFISTUB_MAJOR_VERSION		0x1
 #define LINUX_EFISTUB_MINOR_VERSION		0x0
 
+/*
+ * LINUX_PE_MAGIC appears at offset 0x30 into the MSDOS header of EFI bootable
+ * Linux kernel images that target the architecture as specified by the PE/COFF
+ * header machine type field.
+ */
+#define LINUX_PE_MAGIC	0x818223cd
+
 #define MZ_MAGIC	0x5a4d	/* "MZ" */
 
 #define PE_MAGIC		0x00004550	/* "PE\0\0" */