From 0bd358e4ee0c61355ab057a977fa6f5e311b7f07 Mon Sep 17 00:00:00 2001 From: Alexey Makhalov Date: Fri, 22 Sep 2023 12:25:24 -0700 Subject: [PATCH 2/3] Add .sbat section To be able to revoke previously shipped signed kernel images by SBAT generation. See https://github.com/rhboot/shim/blob/main/SBAT.md Signed-off-by: Alexey Makhalov --- arch/x86/boot/Makefile | 2 +- arch/x86/boot/header.S | 22 ++++++++++++++++++++++ arch/x86/boot/tools/build.c | 33 ++++++++++++++++++++++++++------- security/Kconfig | 12 ++++++++++++ 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 9e38ffaad..c757ce1fb 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -79,7 +79,7 @@ $(obj)/bzImage: asflags-y := $(SVGA_MODE) quiet_cmd_image = BUILD $@ silent_redirect_image = >/dev/null cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \ - $(obj)/zoffset.h $@ $($(quiet)redirect_image) + $(obj)/zoffset.h $@ $(CONFIG_SECURITY_SBAT) $($(quiet)redirect_image) $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE $(call if_changed,image) diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index f912d7770..1c0225fbd 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -232,6 +232,28 @@ section_table: IMAGE_SCN_MEM_DISCARDABLE | \ IMAGE_SCN_ALIGN_1BYTES # Characteristics +#ifdef CONFIG_SECURITY_SBAT + # + # The offset & size fields are filled in by build.c. + # + .ascii ".sbat" + .byte 0 + .byte 0 + .byte 0 + .long 0 # VirtualSize + .long 0 # VirtualAddress + .long 0 # SizeOfRawData + .long 0 # PointerToRawData + .long 0 # PointerToRelocations + .long 0 # PointerToLineNumbers + .word 0 # NumberOfRelocations + .word 0 # NumberOfLineNumbers + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_DISCARDABLE | \ + IMAGE_SCN_ALIGN_1BYTES # Characteristics +#endif + #ifdef CONFIG_EFI_MIXED # # The offset & size fields are filled in by build.c. diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index a3725ad46..d0b803d55 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -195,12 +195,12 @@ static void update_pecoff_section_header(char *section_name, u32 offset, u32 siz update_pecoff_section_header_fields(section_name, offset, size, size, offset); } -static void update_pecoff_setup_and_reloc(unsigned int size) +static void update_pecoff_setup_and_reloc(unsigned int size, unsigned int sbat_size) { u32 setup_offset = 0x200; - u32 reloc_offset = size - PECOFF_RELOC_RESERVE - PECOFF_COMPAT_RESERVE; + u32 reloc_offset = size - PECOFF_RELOC_RESERVE - PECOFF_COMPAT_RESERVE - sbat_size; #ifdef CONFIG_EFI_MIXED - u32 compat_offset = reloc_offset + PECOFF_RELOC_RESERVE; + u32 compat_offset = reloc_offset + PECOFF_RELOC_RESERVE + sbat_size; #endif u32 setup_size = reloc_offset - setup_offset; @@ -304,7 +304,8 @@ static void efi_stub_entry_update(void) #else -static inline void update_pecoff_setup_and_reloc(unsigned int size) {} +static inline void update_pecoff_setup_and_reloc(unsigned int size, + unsigned int sbat_size) {} static inline void update_pecoff_text(unsigned int text_start, unsigned int file_sz, unsigned int init_sz) {} @@ -371,7 +372,7 @@ int main(int argc, char ** argv) { unsigned int i, sz, setup_sectors, init_sz; int c; - u32 sys_size; + u32 sys_size, sbat_size = 0; struct stat sb; FILE *file, *dest; int fd; @@ -380,7 +381,7 @@ int main(int argc, char ** argv) efi_stub_defaults(); - if (argc != 5) + if (argc != 5 && argc != 6) usage(); parse_zoffset(argv[3]); @@ -401,6 +402,13 @@ int main(int argc, char ** argv) die("Boot block hasn't got boot flag (0xAA55)"); fclose(file); + if (argc == 6) { + if (stat(argv[5], &sb)) + die("Unable to stat `%s': %m", argv[5]); + sbat_size = sb.st_size; + memset(buf+c, 0, sbat_size); + c += sbat_size; + } c += reserve_pecoff_compat_section(c); c += reserve_pecoff_reloc_section(c); @@ -411,7 +419,18 @@ int main(int argc, char ** argv) i = setup_sectors*512; memset(buf+c, 0, i-c); - update_pecoff_setup_and_reloc(i); + update_pecoff_setup_and_reloc(i, sbat_size); + if (sbat_size) { + u32 sbat_offset = i - PECOFF_COMPAT_RESERVE - sbat_size; + update_pecoff_section_header(".sbat", sbat_offset, sbat_size); + file = fopen(argv[5], "r"); + if (!file) + die("Unable to open `%s': %m", argv[5]); + if (fread(&buf[sbat_offset], 1, sizeof(buf) - sbat_offset, + file) != sbat_size) + die("Reading sbat failed"); + fclose(file); + } /* Set the default root device */ put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]); diff --git a/security/Kconfig b/security/Kconfig index e6db09a77..536689678 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -206,6 +206,18 @@ source "security/loadpin/Kconfig" source "security/yama/Kconfig" source "security/safesetid/Kconfig" source "security/lockdown/Kconfig" + +config SECURITY_SBAT + string "Add .sbat section to kernel PE image" + depends on SECURITY + help + If set, this option should be the filename of a CSV-formatted file + containing SBAT data to be included as a .sbat section in PE kernel + image (bzImage). + + See for more information + about SBAT. + source "security/landlock/Kconfig" source "security/integrity/Kconfig" -- 2.39.0