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  linux-hardening  linux-cve-announce  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]
Message-Id: <20230818134422.380032-12-ardb@kernel.org>
Date:   Fri, 18 Aug 2023 15:44:16 +0200
From:   Ard Biesheuvel <ardb@...nel.org>
To:     linux-efi@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org, Ard Biesheuvel <ardb@...nel.org>,
        Evgeniy Baskov <baskov@...ras.ru>,
        Borislav Petkov <bp@...en8.de>,
        Dave Hansen <dave.hansen@...ux.intel.com>,
        Ingo Molnar <mingo@...hat.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Peter Jones <pjones@...hat.com>,
        Matthew Garrett <mjg59@...f.ucam.org>,
        Gerd Hoffmann <kraxel@...hat.com>,
        Kees Cook <keescook@...omium.org>,
        "H. Peter Anvin" <hpa@...or.com>,
        Marvin Häuser <mhaeuser@...teo.de>
Subject: [PATCH 11/17] x86/boot: Use fixed size of 16k for setup block

The setup block contains the real mode startup code that is used when
booting from a legacy BIOS, along with the boot_params/setup_data that
is used by legacy x86 bootloaders to pass the command line and initial
ramdisk parameters, among other things.

The setup block also contains the PE/COFF header of the entire combined
image, which includes the compressed kernel image, the decompressor and
the EFI stub.

This PE header describes the layout of the executable image in memory,
and currently, the fact that the setup block precedes it makes it rather
fiddly to get the right values into the right place in the final image.

One complicating factor here is the variable setup block size, and given
that we will need to round up the setup block size to page size anyway
in a subsequent patch (in order to be able to use different permissions
for .text and .data), let's round it up to a fixed size of 16 KiB and be
done with it.

Note that Clang does not optimize for size as aggressively as GCC when
using the -Os option, but it supports -Oz for this purpose, so pass that
if the compiler supports it.

Signed-off-by: Ard Biesheuvel <ardb@...nel.org>
---
 arch/x86/boot/Makefile      |  1 +
 arch/x86/boot/header.S      |  6 +++++-
 arch/x86/boot/setup.ld      |  1 +
 arch/x86/boot/tools/build.c | 12 +++++-------
 4 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 0e98bc5036994715..be1e8b94c93afa4a 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -69,6 +69,7 @@ KBUILD_CFLAGS	:= $(REALMODE_CFLAGS) -D_SETUP
 KBUILD_AFLAGS	:= $(KBUILD_CFLAGS) -D__ASSEMBLY__
 KBUILD_CFLAGS	+= $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
 KBUILD_CFLAGS	+= -fno-asynchronous-unwind-tables
+KBUILD_CFLAGS	+= $(call cc-option,-Oz)
 GCOV_PROFILE := n
 UBSAN_SANITIZE := n
 
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 72744ba440f6ea09..bef9265173757a5a 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -36,6 +36,10 @@ SYSSEG		= 0x1000		/* historical load address >> 4 */
 #define ROOT_RDONLY 1
 #endif
 
+	/* The setup block has a fixed size: 32 * 512 == 16k */
+	.globl	setup_size
+	.set	setup_size, 0x4000
+
 	.code16
 	.section ".bstext", "ax"
 #ifdef CONFIG_EFI_STUB
@@ -231,7 +235,7 @@ sentinel:	.byte 0xff, 0xff        /* Used to detect broken loaders */
 
 	.globl	hdr
 hdr:
-setup_sects:	.byte 0			/* Filled in by build.c */
+setup_sects:	.byte (setup_size / 512) - 1
 root_flags:	.word ROOT_RDONLY
 syssize:	.long 0			/* Filled in by build.c */
 ram_size:	.word 0			/* Obsolete */
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index a05dcaa4b74cd9f8..f1c14616cd80390d 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -57,6 +57,7 @@ SECTIONS
 	}
 
 	ASSERT(_end <= 0x8000, "Setup too big!")
+	ASSERT(__bss_start <= setup_size, "Setup image size too big!")
 	ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!")
 	/* Necessary for the very-old-loader check to work... */
 	ASSERT(__end_init <= 5*512, "init sections too big!")
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 06949754316458ce..665ce7241542e475 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -40,12 +40,10 @@ typedef unsigned char  u8;
 typedef unsigned short u16;
 typedef unsigned int   u32;
 
-/* Minimal number of setup sectors */
-#define SETUP_SECT_MIN 5
-#define SETUP_SECT_MAX 64
+#define SETUP_SECT_NUM 32
 
 /* This must be large enough to hold the entire setup */
-u8 buf[SETUP_SECT_MAX*512];
+u8 buf[(SETUP_SECT_NUM+1)*512];
 
 #define PECOFF_RELOC_RESERVE 0x20
 
@@ -360,8 +358,9 @@ int main(int argc, char ** argv)
 
 	/* Pad unused space with zeros */
 	setup_sectors = (c + 511) / 512;
-	if (setup_sectors < SETUP_SECT_MIN)
-		setup_sectors = SETUP_SECT_MIN;
+	if (setup_sectors > SETUP_SECT_NUM)
+		die("setup size exceeds maximum");
+	setup_sectors = SETUP_SECT_NUM;
 	i = setup_sectors*512;
 	memset(buf+c, 0, i-c);
 
@@ -388,7 +387,6 @@ int main(int argc, char ** argv)
 #endif
 
 	/* Patch the setup code with the appropriate size parameters */
-	buf[0x1f1] = setup_sectors-1;
 	put_unaligned_le32(sys_size, &buf[0x1f4]);
 
 	update_pecoff_text(setup_sectors * 512, i + (sys_size * 16));
-- 
2.39.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ