lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 24 May 2019 11:55:03 +0200
From:   Daniel Kiper <daniel.kiper@...cle.com>
To:     linux-kernel@...r.kernel.org, x86@...nel.org
Cc:     dpsmith@...rtussolutions.com, eric.snowberg@...cle.com,
        hpa@...or.com, kanth.ghatraju@...cle.com, konrad.wilk@...cle.com,
        ross.philipson@...cle.com
Subject: [PATCH RFC 1/2] x86/boot: Introduce the setup_header2

Due to limited space left in the setup header it was decided to
introduce the setup_header2. Its role is to communicate Linux kernel
supported features to the boot loader. Starting from now this is the
primary way to communicate things to the boot loader.

Suggested-by: H. Peter Anvin <hpa@...or.com>
Signed-off-by: Daniel Kiper <daniel.kiper@...cle.com>
Reviewed-by: Ross Philipson <ross.philipson@...cle.com>
Reviewed-by: Eric Snowberg <eric.snowberg@...cle.com>
---
I know that setup_header2 is not the best name. There were some
alternatives proposed like setup_header_extra, setup_header_addendum,
setup_header_more, ext_setup_header, extended_setup_header, extended_header
and extended_setup. Sadly, I am not happy with any of them. So,
leaving setup_header2 as is but still looking for better name.
Probably shorter == better...
---
 Documentation/x86/boot.txt               | 49 ++++++++++++++++++++++++++++++++
 arch/x86/boot/Makefile                   |  2 +-
 arch/x86/boot/compressed/Makefile        |  4 +--
 arch/x86/boot/compressed/setup_header2.S | 12 ++++++++
 arch/x86/boot/header.S                   |  3 +-
 arch/x86/boot/tools/build.c              |  8 ++++++
 arch/x86/include/uapi/asm/bootparam.h    |  1 +
 7 files changed, 75 insertions(+), 4 deletions(-)
 create mode 100644 arch/x86/boot/compressed/setup_header2.S

diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index f4c2a97bfdbd..ff10c6116662 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -61,6 +61,22 @@ Protocol 2.12:	(Kernel 3.8) Added the xloadflags field and extension fields
 		to struct boot_params for loading bzImage and ramdisk
 		above 4G in 64bit.
 
+Protocol 2.14:	BURNT BY INCORRECT COMMIT ae7e1238e68f2a472a125673ab506d49158c1889
+		(x86/boot: Add ACPI RSDP address to setup_header)
+		DO NOT USE!!! ASSUME SAME AS 2.13.
+
+Protocol 2.15:	(Kernel 5.2) Added the setup_header2.
+
+Note: The protocol version number should be changed only if the setup header
+      is changed. There is no need to update the version number if boot_params
+      or setup_header2 are changed. Additionally, it is recommended to use
+      xloadflags (in this case the protocol version number should not be
+      updated either) or setup_header2 to communicate supported Linux kernel
+      features to the boot loader. Due to very limited space available in
+      the original setup header every update to it should be considered
+      with great care. Starting from the protocol 2.15 the primary way to
+      communicate things to the boot loader is the setup_header2.
+
 **** MEMORY LAYOUT
 
 The traditional memory map for the kernel loader, used for Image or
@@ -197,6 +213,7 @@ Offset	Proto	Name		Meaning
 0258/8	2.10+	pref_address	Preferred loading address
 0260/4	2.10+	init_size	Linear memory required during initialization
 0264/4	2.11+	handover_offset	Offset of handover entry point
+0268/4	2.15+	setup_header2_offset Offset of the setup_header2
 
 (1) For backwards compatibility, if the setup_sects field contains 0, the
     real value is 4.
@@ -744,6 +761,38 @@ Offset/size:	0x264/4
 
   See EFI HANDOVER PROTOCOL below for more details.
 
+Field name:	setup_header2_offset
+Type:		read
+Offset/size:	0x268/4
+Protocol:	2.15+
+
+  This field is the offset from the beginning of the kernel image to the
+  setup_header2. It is embedded in the Linux image in the uncompressed
+  protected mode region.
+
+
+**** THE SETUP_HEADER2
+
+Due to limited space left in the setup header it was decided to introduce
+the setup_header2. Its role is to communicate Linux kernel supported features
+to the boot loader. All fields of the setup_header2 are read only from the
+boot loader point of view. The setup_header2 is supported starting from the
+boot protocol version 2.15.
+
+
+**** DETAILS OF THE SETUP_HEADER2 FIELDS
+
+Field name:	header
+Offset/size:	0x0000/4
+
+  Contains the magic number "hDR2" (0x68445232).
+
+Field name:	size
+Offset/size:	0x0004/4
+
+  This field contains the size of the setup_header2 including setup_header2.header.
+  It should be used by the boot loader to detect supported fields in the setup_header2.
+
 
 **** THE IMAGE CHECKSUM
 
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index e2839b5c246c..c11b57da90f6 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -87,7 +87,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
 
 SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
 
-sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p'
+sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|setup_header2\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p'
 
 quiet_cmd_zoffset = ZOFFSET $@
       cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 6b84afdd7538..c12ccc2bd923 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -72,8 +72,8 @@ $(obj)/../voffset.h: vmlinux FORCE
 
 $(obj)/misc.o: $(obj)/../voffset.h
 
-vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \
-	$(obj)/string.o $(obj)/cmdline.o $(obj)/error.o \
+vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/setup_header2.o $(obj)/head_$(BITS).o \
+	$(obj)/misc.o $(obj)/string.o $(obj)/cmdline.o $(obj)/error.o \
 	$(obj)/piggy.o $(obj)/cpuflags.o
 
 vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o
diff --git a/arch/x86/boot/compressed/setup_header2.S b/arch/x86/boot/compressed/setup_header2.S
new file mode 100644
index 000000000000..0b3963296825
--- /dev/null
+++ b/arch/x86/boot/compressed/setup_header2.S
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+	.section ".rodata.setup_header2", "a"
+
+	.global setup_header2
+
+setup_header2:
+        /* Header. */
+	.ascii	"hDR2"
+        /* Size. */
+	.long	setup_header2_end - setup_header2
+setup_header2_end:
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 850b8762e889..72387b1e359c 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -300,7 +300,7 @@ _start:
 	# Part 2 of the header, from the old setup.S
 
 		.ascii	"HdrS"		# header signature
-		.word	0x020d		# header version number (>= 0x0105)
+		.word	0x020f		# header version number (>= 0x0105)
 					# or else old loadlin-1.5 will fail)
 		.globl realmode_swtch
 realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
@@ -557,6 +557,7 @@ pref_address:		.quad LOAD_PHYSICAL_ADDR	# preferred load addr
 
 init_size:		.long INIT_SIZE		# kernel initialization size
 handover_offset:	.long 0			# Filled in by build.c
+setup_header2_offset:	.long 0			# Filled in by build.c
 
 # End of setup header #####################################################
 
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index a93d44e58f9c..7fc9425a0fc9 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -56,6 +56,7 @@ u8 buf[SETUP_SECT_MAX*512];
 unsigned long efi32_stub_entry;
 unsigned long efi64_stub_entry;
 unsigned long efi_pe_entry;
+unsigned long setup_header2;
 unsigned long startup_64;
 
 /*----------------------------------------------------------------------*/
@@ -289,6 +290,10 @@ static inline int reserve_pecoff_reloc_section(int c)
 }
 #endif /* CONFIG_EFI_STUB */
 
+static void setup_header2_offset_update(void)
+{
+	put_unaligned_le32(setup_header2, &buf[0x268]);
+}
 
 /*
  * Parse zoffset.h and find the entry points. We could just #include zoffset.h
@@ -321,6 +326,7 @@ static void parse_zoffset(char *fname)
 		PARSE_ZOFS(p, efi32_stub_entry);
 		PARSE_ZOFS(p, efi64_stub_entry);
 		PARSE_ZOFS(p, efi_pe_entry);
+		PARSE_ZOFS(p, setup_header2);
 		PARSE_ZOFS(p, startup_64);
 
 		p = strchr(p, '\n');
@@ -410,6 +416,8 @@ int main(int argc, char ** argv)
 
 	efi_stub_entry_update();
 
+	setup_header2_offset_update();
+
 	crc = partial_crc32(buf, i, crc);
 	if (fwrite(buf, 1, i, dest) != i)
 		die("Writing setup failed");
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 60733f137e9a..77b48c7a23b4 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -86,6 +86,7 @@ struct setup_header {
 	__u64	pref_address;
 	__u32	init_size;
 	__u32	handover_offset;
+	__u32	setup_header2_offset;
 } __attribute__((packed));
 
 struct sys_desc_table {
-- 
2.11.0

Powered by blists - more mailing lists