From 6d13718c806680f78157483906b04486775f5252 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 12 Feb 2021 16:29:16 +0100 Subject: [PATCH] Add a .sbat section to EFI binaries The Secure Boot Advanced Targeting (SBAT) [0] is a Generation Number Based Revocation mechanism that is meant to replace the DBX revocation file list. Binaries must contain a .sbat data section that has a set entries, each of them consisting of UTF-8 strings as comma separated values. Allow to embed this information into the fwupd EFI binary at build time. The SBAT metadata must contain at least two entries. One that defines the SBAT version used and another one that defines the component generation. This patch adds a sbat.csv that contains these two entries and downstream users can override if additional entries are needed due changes that make them diverge from upstream code and potentially add other vulnerabilities. The same SBAT metadata is added to the fallback and MOK manager binaries because these are built from the same shim source. These need to have SBAT metadata as well to be booted if a .sbat section is mandatory. [0]: https://github.com/rhboot/shim/blob/sbat/SBAT.md Signed-off-by: Javier Martinez Canillas --- Make.defaults | 1 + Makefile | 18 +++++++++++------- data/sbat.csv | 2 ++ elf_aarch64_efi.lds | 7 ++++++- elf_arm_efi.lds | 7 ++++++- elf_ia32_efi.lds | 7 +++++++ elf_ia64_efi.lds | 7 +++++++ elf_x86_64_efi.lds | 7 +++++++ sbat.c | 0 9 files changed, 47 insertions(+), 9 deletions(-) create mode 100755 data/sbat.csv create mode 100644 sbat.c diff --git a/Make.defaults b/Make.defaults index 811db71..10e1ad5 100644 --- a/Make.defaults +++ b/Make.defaults @@ -22,6 +22,7 @@ DEBUGSOURCE ?= $(prefix)/src/debug/ OSLABEL ?= $(EFIDIR) DEFAULT_LOADER ?= \\\\grub$(ARCH_SUFFIX).efi DASHJ ?= -j$(shell echo $$(($$(grep -c "^model name" /proc/cpuinfo) + 1))) +SBATPATH ?= data/sbat.csv ARCH ?= $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,) OBJCOPY_GTE224 = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.*\((.*)\|version\) //g' | cut -f1-2 -d.` \>= 2.24) diff --git a/Makefile b/Makefile index a17fa2b..63867f9 100644 --- a/Makefile +++ b/Makefile @@ -33,12 +33,12 @@ CFLAGS += -DENABLE_SHIM_CERT else TARGETS += $(MMNAME) $(FBNAME) endif -OBJS = shim.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o +OBJS = shim.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer ORIG_SOURCES = shim.c mok.c netboot.c replacements.c tpm.c errlog.c shim.h version.h $(wildcard include/*.h) -MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o +MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat.o ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h) -FALLBACK_OBJS = fallback.o tpm.o errlog.o +FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat.o ORIG_FALLBACK_SRCS = fallback.c ifneq ($(origin ENABLE_HTTPBOOT), undefined) @@ -84,6 +84,10 @@ shim.o: $(wildcard $(TOPDIR)/*.h) cert.o : $(TOPDIR)/cert.S $(CC) $(CFLAGS) -c -o $@ $< +sbat.o : $(TOPDIR)/sbat.c + $(CC) $(CFLAGS) -c -o $@ $< + $(OBJCOPY) --add-section .sbat=$(SBATPATH) $@ + $(SHIMNAME) : $(SHIMSONAME) $(MMNAME) : $(MMSONAME) $(FBNAME) : $(FBSONAME) @@ -192,8 +196,8 @@ endif $(OBJCOPY) -D -j .text -j .sdata -j .data -j .data.ident \ -j .dynamic -j .dynsym -j .rel* \ -j .rela* -j .reloc -j .eh_frame \ - -j .vendor_cert \ - $(FORMAT) $^ $@ + -j .vendor_cert -j .sbat \ + $(FORMAT) $< $@ # I am tired of wasting my time fighting binutils timestamp code. dd conv=notrunc bs=1 count=4 seek=$(TIMESTAMP_LOCATION) if=/dev/zero of=$@ @@ -208,11 +212,11 @@ ifneq ($(OBJCOPY_GTE224),1) endif $(OBJCOPY) -D -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel* \ - -j .rela* -j .reloc -j .eh_frame \ + -j .rela* -j .reloc -j .eh_frame -j .sbat \ -j .debug_info -j .debug_abbrev -j .debug_aranges \ -j .debug_line -j .debug_str -j .debug_ranges \ -j .note.gnu.build-id \ - $^ $@ + $< $@ ifneq ($(origin ENABLE_SBSIGN),undefined) %.efi.signed: %.efi shim.key shim.crt diff --git a/data/sbat.csv b/data/sbat.csv new file mode 100755 index 0000000..08a2459 --- /dev/null +++ b/data/sbat.csv @@ -0,0 +1,2 @@ +sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md +shim,0,UEFI shim,shim,0,https://github.com/rhboot/shim diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds index 96f15d5..48ba8ba 100644 --- a/elf_aarch64_efi.lds +++ b/elf_aarch64_efi.lds @@ -58,7 +58,12 @@ SECTIONS *(.vendor_cert) } . = ALIGN(4096); - + .sbat : + { + _sbat = .; + *(.sbat) + _esbat = .; + } . = ALIGN(4096); .rela : { diff --git a/elf_arm_efi.lds b/elf_arm_efi.lds index b12424e..7d69948 100644 --- a/elf_arm_efi.lds +++ b/elf_arm_efi.lds @@ -56,7 +56,12 @@ SECTIONS *(.vendor_cert) } . = ALIGN(4096); - + .sbat : + { + _sbat = .; + *(.sbat) + _esbat = .; + } . = ALIGN(4096); .rel : { diff --git a/elf_ia32_efi.lds b/elf_ia32_efi.lds index deec2ec..043a358 100644 --- a/elf_ia32_efi.lds +++ b/elf_ia32_efi.lds @@ -54,6 +54,13 @@ SECTIONS *(.vendor_cert) } . = ALIGN(4096); + .sbat : + { + _sbat = .; + *(.sbat) + _esbat = .; + } + . = ALIGN(4096); .dynamic : { *(.dynamic) } . = ALIGN(4096); .rel : diff --git a/elf_ia64_efi.lds b/elf_ia64_efi.lds index e7d85e2..ce2e34c 100644 --- a/elf_ia64_efi.lds +++ b/elf_ia64_efi.lds @@ -56,6 +56,13 @@ SECTIONS *(.vendor_cert) } . = ALIGN(4096); + .sbat : + { + _sbat = .; + *(.sbat) + _esbat = .; + } + . = ALIGN(4096); .dynamic : { *(.dynamic) } . = ALIGN(4096); .rela : diff --git a/elf_x86_64_efi.lds b/elf_x86_64_efi.lds index 1f561b2..3e1f138 100644 --- a/elf_x86_64_efi.lds +++ b/elf_x86_64_efi.lds @@ -59,6 +59,13 @@ SECTIONS *(.vendor_cert) } . = ALIGN(4096); + .sbat : + { + _sbat = .; + *(.sbat) + _esbat = .; + } + . = ALIGN(4096); .dynamic : { *(.dynamic) } . = ALIGN(4096); .rela : diff --git a/sbat.c b/sbat.c new file mode 100644 index 0000000..e69de29