]> git.proxmox.com Git - efi-boot-shim.git/commitdiff
New upstream version 15.4
authorSteve McIntyre <steve@einval.com>
Wed, 31 Mar 2021 17:24:24 +0000 (18:24 +0100)
committerSteve McIntyre <steve@einval.com>
Wed, 31 Mar 2021 17:24:24 +0000 (18:24 +0100)
16 files changed:
.github/workflows/pullrequest.yml
Make.defaults
Makefile
commit
csv.c
elf_aarch64_efi.lds
elf_arm_efi.lds
gnu-efi/Make.defaults
gnu-efi/gnuefi/crt0-efi-aarch64.S
gnu-efi/gnuefi/crt0-efi-arm.S
include/sbat.h
lib/Makefile
pe.c
sbat.c
shim.c
test-sbat.c

index 41ca282c887624f304aee769d0f420e45de7a0d5..5329496c6a8599bd8553196ae5d271e6c21b1b16 100644 (file)
@@ -110,14 +110,24 @@ jobs:
         id: update-submodules
         run: |
           make update
+      - name: Make a build directory for ${{ matrix.distro }} for ${{ matrix.efiarch }}
+        id: builddir
+        run: |
+          rm -rf build-${{ matrix.distro }}-${{ matrix.efiarch }}
+          mkdir build-${{ matrix.distro }}-${{ matrix.efiarch }}
+          cd build-${{ matrix.distro }}-${{ matrix.efiarch }}
       - name: Do the build on ${{ matrix.distro }} for ${{ matrix.efiarch }}
         id: build
         run: |
-          make -s CROSS_COMPILE=${{ matrix.gccarch }}-linux-gnu- ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true clean all || make CROSS_COMPILE=${{ matrix.gccarch }}-linux-gnu- ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true clean all
+          pwd
+          cd build-${{ matrix.distro }}-${{ matrix.efiarch }}
+          make TOPDIR=.. -f ../Makefile CROSS_COMPILE=${{ matrix.gccarch }}-linux-gnu- ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true all
       - name: Install on ${{ matrix.distro }} for ${{ matrix.efiarch }}
         id: install
         run: |
-          make -s CROSS_COMPILE=${{ matrix.gccarch }}-linux-gnu- ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true install || make CROSS_COMPILE=${{ matrix.gccarch }}-linux-gnu- ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true install
+          pwd
+          cd build-${{ matrix.distro }}-${{ matrix.efiarch }}
+          make TOPDIR=.. -f ../Makefile CROSS_COMPILE=${{ matrix.gccarch }}-linux-gnu- ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true install
           echo 'results:'
           find /destdir -type f
 
@@ -190,17 +200,21 @@ jobs:
         id: update-submodules
         run: |
           make update
+      - name: Do 'make clean' on ${{ matrix.distro }} for ${{ matrix.efiarch }}
+        id: clean
+        run: |
+          make ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true clean
       - name: Run tests on ${{ matrix.distro }} for ${{ matrix.efiarch }}
         id: test
         run: |
-          make -s ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true test || make ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true test
+          make ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true test
       - name: Do the build on ${{ matrix.distro }} for ${{ matrix.efiarch }}
         id: build
         run: |
-          make -s ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true clean all || make ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true clean all
+          make ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true all
       - name: Install on ${{ matrix.distro }} for ${{ matrix.efiarch }}
         id: install
         run: |
-          make -s ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true install || make ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true install
+          make ARCH=${{ matrix.makearch }} PREFIX=/usr DESTDIR=/destdir EFIDIR=test ENABLE_SHIM_HASH=true install
           echo 'results:'
           find /destdir -type f
index b7721547deec1084701681fd9b21f090276404c5..a775083ee0b60c49c9b1f014618af349ba68798c 100644 (file)
@@ -1,6 +1,7 @@
 
 # load the local configuration if it exists
 -include Make.local
+-include $(TOPDIR)/Make.local
 
 COMPILER       ?= gcc
 CC             = $(CROSS_COMPILE)$(COMPILER)
index e349c6f9d494955501de0a5f83d0a1d29d2c465d..8c66459c4f33932173865fdc0a0a644360f0467e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 default : all
 
 NAME           = shim
-VERSION                = 15.3
+VERSION                = 15.4
 ifneq ($(origin RELEASE),undefined)
 DASHRELEASE    ?= -$(RELEASE)
 else
@@ -45,7 +45,7 @@ MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o
 ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h)
 FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o
 ORIG_FALLBACK_SRCS = fallback.c
-SBATPATH = data/sbat.csv
+SBATPATH = $(TOPDIR)/data/sbat.csv
 
 ifeq ($(SOURCE_DATE_EPOCH),)
        UNAME=$(shell uname -s -m -p -i -o)
@@ -111,7 +111,7 @@ sbat.%.csv : data/sbat.%.csv
        $(DOS2UNIX) $(D2UFLAGS) $< $@
        tail -c1 $@ | read -r _ || echo >> $@ # ensure a trailing newline
 
-VENDOR_SBATS := $(foreach x,$(wildcard data/sbat.*.csv),$(notdir $(x)))
+VENDOR_SBATS := $(sort $(foreach x,$(wildcard $(TOPDIR)/data/sbat.*.csv data/sbat.*.csv),$(notdir $(x))))
 
 sbat_data.o : | $(SBATPATH) $(VENDOR_SBATS)
 sbat_data.o : /dev/null
@@ -146,21 +146,23 @@ $(MMSONAME): $(MOK_OBJS) $(LIBS)
 
 gnu-efi/$(ARCH_GNUEFI)/gnuefi/libgnuefi.a gnu-efi/$(ARCH_GNUEFI)/lib/libefi.a: CFLAGS+=-DGNU_EFI_USE_EXTERNAL_STDARG
 gnu-efi/$(ARCH_GNUEFI)/gnuefi/libgnuefi.a gnu-efi/$(ARCH_GNUEFI)/lib/libefi.a:
+       mkdir -p gnu-efi/lib gnu-efi/gnuefi
        $(MAKE) -C gnu-efi \
                ARCH=$(ARCH_GNUEFI) TOPDIR=$(TOPDIR)/gnu-efi \
+               -f $(TOPDIR)/gnu-efi/Makefile \
                lib gnuefi inc
 
 Cryptlib/libcryptlib.a:
        for i in Hash Hmac Cipher Rand Pk Pem SysCall; do mkdir -p Cryptlib/$$i; done
-       $(MAKE) VPATH=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile
+       $(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile
 
 Cryptlib/OpenSSL/libopenssl.a:
        for i in x509v3 x509 txt_db stack sha rsa rc4 rand pkcs7 pkcs12 pem ocsp objects modes md5 lhash kdf hmac evp err dso dh conf comp cmac buffer bn bio async/arch asn1 aes; do mkdir -p Cryptlib/OpenSSL/crypto/$$i; done
-       $(MAKE) VPATH=$(TOPDIR)/Cryptlib/OpenSSL -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile
+       $(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib/OpenSSL -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile
 
 lib/lib.a: | $(TOPDIR)/lib/Makefile $(wildcard $(TOPDIR)/include/*.[ch])
-       if [ ! -d lib ]; then mkdir lib ; fi
-       $(MAKE) VPATH=$(TOPDIR)/lib -C lib -f $(TOPDIR)/lib/Makefile lib.a
+       mkdir -p lib
+       $(MAKE) VPATH=$(TOPDIR)/lib TOPDIR=$(TOPDIR) -C lib -f $(TOPDIR)/lib/Makefile
 
 buildid : $(TOPDIR)/buildid.c
        $(HOSTCC) -I/usr/include -Og -g3 -Wall -Werror -Wextra -o $@ $< -lelf
@@ -223,6 +225,7 @@ endif
 install-as-data : install-deps
        $(INSTALL) -d -m 0755 $(DESTDIR)/$(DATATARGETDIR)
        $(INSTALL) -m 0644 $(SHIMNAME) $(DESTDIR)/$(DATATARGETDIR)/
+       $(INSTALL) -m 0644 $(BOOTCSVNAME) $(DESTDIR)/$(DATATARGETDIR)/
 ifneq ($(origin ENABLE_SHIM_HASH),undefined)
        $(INSTALL) -m 0644 $(SHIMHASHNAME) $(DESTDIR)/$(DATATARGETDIR)/
 endif
@@ -239,7 +242,7 @@ ifneq ($(OBJCOPY_GTE224),1)
        $(error objcopy >= 2.24 is required)
 endif
        $(OBJCOPY) -D -j .text -j .sdata -j .data -j .data.ident \
-               -j .dynamic -j .dynsym -j .rel* \
+               -j .dynamic -j .rodata -j .rel* \
                -j .rela* -j .reloc -j .eh_frame \
                -j .vendor_cert -j .sbat \
                $(FORMAT) $< $@
@@ -256,7 +259,7 @@ ifneq ($(OBJCOPY_GTE224),1)
        $(error objcopy >= 2.24 is required)
 endif
        $(OBJCOPY) -D -j .text -j .sdata -j .data \
-               -j .dynamic -j .dynsym -j .rel* \
+               -j .dynamic -j .rodata -j .rel* \
                -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 \
@@ -275,35 +278,46 @@ else
 endif
 
 test :
-       @make -f include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" all
+       @make -f $(TOPDIR)/include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" all
 
 $(patsubst %.c,%,$(wildcard test-*.c)) :
-       @make -f include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" $@
+       @make -f $(TOPDIR)/include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" $@
 
 .PHONY : $(patsubst %.c,%,$(wildcard test-*.c)) test
 
 clean-test-objs:
-       @make -f include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" clean
+       @make -f $(TOPDIR)/include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" clean
 
 clean-gnu-efi:
-       $(MAKE) -C gnu-efi \
-               ARCH=$(ARCH_GNUEFI) TOPDIR=$(TOPDIR)/gnu-efi \
-               clean
+       @if [ -d gnu-efi ] ; then \
+               $(MAKE) -C gnu-efi \
+                       ARCH=$(ARCH_GNUEFI) TOPDIR=$(TOPDIR)/gnu-efi \
+                       -f $(TOPDIR)/gnu-efi/Makefile \
+                       clean ; \
+       fi
+
+clean-lib-objs:
+       @if [ -d lib ] ; then \
+               $(MAKE) -C lib TOPDIR=$(TOPDIR) -f $(TOPDIR)/lib/Makefile clean ; \
+       fi
 
 clean-shim-objs:
-       $(MAKE) -C lib -f $(TOPDIR)/lib/Makefile clean
        @rm -rvf $(TARGET) *.o $(SHIM_OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb $(BOOTCSVNAME)
        @rm -vf *.debug *.so *.efi *.efi.* *.tar.* version.c buildid
        @rm -vf Cryptlib/*.[oa] Cryptlib/*/*.[oa]
        @if [ -d .git ] ; then git clean -f -d -e 'Cryptlib/OpenSSL/*'; fi
 
 clean-openssl-objs:
-       $(MAKE) -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile clean
+       @if [ -d Cryptlib/OpenSSL ] ; then \
+               $(MAKE) -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile clean ; \
+       fi
 
 clean-cryptlib-objs:
-       $(MAKE) -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile clean
+       @if [ -d Cryptlib ] ; then \
+               $(MAKE) -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile clean ; \
+       fi
 
-clean: clean-shim-objs clean-test-objs clean-gnu-efi clean-openssl-objs clean-cryptlib-objs
+clean: clean-shim-objs clean-test-objs clean-gnu-efi clean-openssl-objs clean-cryptlib-objs clean-lib-objs
 
 GITTAG = $(VERSION)
 
diff --git a/commit b/commit
index 8ab60cd500ebe728ab81bac9e6dfd0b3ccd560ed..6ab67e7e26da01b0d8aee456b83bdf83dc46cd1d 100644 (file)
--- a/commit
+++ b/commit
@@ -1 +1 @@
-630b8dedfd8434353bce80ff89f63fd3113b086d
\ No newline at end of file
+20e4d9486fcae54ee44d2323ae342ffe68c920e6
\ No newline at end of file
diff --git a/csv.c b/csv.c
index d141f03543e5b2e0310aaf1fcbe17ccb60679f7e..f6b37f150f09eaaccd352d1b2df60fbc83b45521 100644 (file)
--- a/csv.c
+++ b/csv.c
@@ -55,8 +55,11 @@ parse_csv_data(char *data, char *data_end, size_t n_columns, list_t *list)
        size_t max = 0;
        char *end = data_end;
 
-       if (!data || !end || end <= data || !n_columns || !list)
+       if (!data || !end || end <= data || !n_columns || !list) {
+               dprint(L"data:0x%lx end:0x%lx n_columns:%lu list:0x%lx\n",
+                      data, end, n_columns, list);
                return EFI_INVALID_PARAMETER;
+       }
 
        max = (uintptr_t)end - (uintptr_t)line + (end > line ? 1 : 0);
 
index feb4ead921193c3abd8846ce3acf1e96741ef246..353b24a0533995eaac1b180d681ed6a581569d15 100644 (file)
@@ -9,24 +9,12 @@ SECTIONS
     *(.text)
     *(.text.*)
     *(.gnu.linkonce.t.*)
-    *(.srodata)
-    *(.rodata*)
-    . = ALIGN(16);
-    _etext = .;
-  }
-
-  . = ALIGN(4096);
-  .dynamic  : { *(.dynamic) }
-
-  . = ALIGN(4096);
-  .note.gnu.build-id : {
-    *(.note.gnu.build-id)
-  }
-
-  . = ALIGN(4096);
-  .data.ident : {
-    *(.data.ident)
+    _evtext = .;
+    . = ALIGN(4096);
   }
+  _etext = .;
+  _text_size = . - _text;
+  _text_vsize = _evtext - _text;
 
   . = ALIGN(4096);
   .data :
@@ -39,6 +27,8 @@ SECTIONS
    *(.got.plt)
    *(.got)
 
+   *(.dynamic)
+
    /* the EFI loader doesn't seem to like a .bss section, so we stick
       it all into .data: */
    . = ALIGN(16);
@@ -48,44 +38,61 @@ SECTIONS
    *(.dynbss)
    *(.bss)
    *(COMMON)
-   . = ALIGN(16);
+   _evdata = .;
+   . = ALIGN(4096);
    _bss_end = .;
   }
+  _edata = .;
+  _data_vsize = _evdata - _data;
+  _data_size = . - _data;
 
+  /*
+   * Note that _sbat must be the beginning of the data, and _esbat must be the
+   * end and must be before any section padding.  The sbat self-check uses
+   * _esbat to find the bounds of the data, and if the padding is included, the
+   * CSV parser (correctly) rejects the data as having NUL values in one of the
+   * required columns.
+   */
   . = ALIGN(4096);
-  .vendor_cert :
+  .sbat :
   {
-    *(.vendor_cert)
+    _sbat = .;
+    *(.sbat)
+    *(.sbat.*)
+    _esbat = .;
+    . = ALIGN(4096);
+    _epsbat = .;
   }
+  _sbat_size = _epsbat - _sbat;
+  _sbat_vsize = _esbat - _sbat;
+
   . = ALIGN(4096);
-  .rela :
+  .rodata :
   {
+    _rodata = .;
     *(.rela.dyn)
     *(.rela.plt)
     *(.rela.got)
     *(.rela.data)
     *(.rela.data*)
+
+    *(.rodata*)
+    *(.srodata)
+    *(.dynsym)
+    *(.dynstr)
+    . = ALIGN(16);
+    *(.note.gnu.build-id)
+    . = ALIGN(4096);
+    *(.vendor_cert)
+    *(.data.ident)
+    _evrodata = .;
+    . = ALIGN(4096);
   }
-  _edata = .;
-  _data_size = . - _data;
-  . = ALIGN(4096);
-  .sbat :
-  {
-    _sbat = .;
-    *(.sbat)
-    *(.sbat.*)
-  }
-  _esbat = .;
-  _sbat_vsize = . - _sbat;
-  . = ALIGN(4096);
-  _sbat_size = . - _sbat;
+  _erodata = .;
+  _rodata_size = . - _rodata;
+  _rodata_vsize = _evrodata - _rodata;
   _alldata_size = . - _data;
 
-  . = ALIGN(4096);
-  .dynsym   : { *(.dynsym) }
-  . = ALIGN(4096);
-  .dynstr   : { *(.dynstr) }
-  . = ALIGN(4096);
   /DISCARD/ :
   {
     *(.rel.reloc)
index d7de181f9bb4535943918a8994623f587c2ef7fb..e4e29bdf3b15c3507b265a246575e171592ed399 100644 (file)
@@ -9,22 +9,12 @@ SECTIONS
     *(.text)
     *(.text.*)
     *(.gnu.linkonce.t.*)
-    *(.srodata)
-    *(.rodata*)
-    . = ALIGN(16);
-    _etext = .;
-  }
-  .dynamic  : { *(.dynamic) }
-
-  . = ALIGN(4096);
-  .note.gnu.build-id : {
-    *(.note.gnu.build-id)
-  }
-
-  . = ALIGN(4096);
-  .data.ident : {
-    *(.data.ident)
+    _evtext = .;
+    . = ALIGN(4096);
   }
+  _etext = .;
+  _text_size = . - _text;
+  _text_vsize = _evtext - _text;
 
   . = ALIGN(4096);
   .data :
@@ -33,10 +23,12 @@ SECTIONS
    *(.sdata)
    *(.data)
    *(.data1)
-   *(.data*)
+   *(.data.*)
    *(.got.plt)
    *(.got)
 
+   *(.dynamic)
+
    /* the EFI loader doesn't seem to like a .bss section, so we stick
       it all into .data: */
    . = ALIGN(16);
@@ -46,44 +38,61 @@ SECTIONS
    *(.dynbss)
    *(.bss)
    *(COMMON)
-   . = ALIGN(16);
+   _evdata = .;
+   . = ALIGN(4096);
    _bss_end = .;
   }
+  _edata = .;
+  _data_vsize = _evdata - _data;
+  _data_size = . - _data;
 
+  /*
+   * Note that _sbat must be the beginning of the data, and _esbat must be the
+   * end and must be before any section padding.  The sbat self-check uses
+   * _esbat to find the bounds of the data, and if the padding is included, the
+   * CSV parser (correctly) rejects the data as having NUL values in one of the
+   * required columns.
+   */
   . = ALIGN(4096);
-  .vendor_cert :
+  .sbat :
   {
-    *(.vendor_cert)
+    _sbat = .;
+    *(.sbat)
+    *(.sbat.*)
+    _esbat = .;
+    . = ALIGN(4096);
+    _epsbat = .;
   }
+  _sbat_size = _epsbat - _sbat;
+  _sbat_vsize = _esbat - _sbat;
+
   . = ALIGN(4096);
-  .rel :
+  .rodata :
   {
+    _rodata = .;
     *(.rel.dyn)
     *(.rel.plt)
     *(.rel.got)
     *(.rel.data)
     *(.rel.data*)
+
+    *(.rodata*)
+    *(.srodata)
+    *(.dynsym)
+    *(.dynstr)
+    . = ALIGN(16);
+    *(.note.gnu.build-id)
+    . = ALIGN(4096);
+    *(.vendor_cert)
+    *(.data.ident)
+    _evrodata = .;
+    . = ALIGN(4096);
   }
-  _edata = .;
-  _data_size = . - _data;
-  . = ALIGN(4096);
-  .sbat :
-  {
-    _sbat = .;
-    *(.sbat)
-    *(.sbat.*)
-  }
-  _esbat = .;
-  _sbat_vsize = . - _sbat;
-  . = ALIGN(4096);
-  _sbat_size = . - _sbat;
+  _erodata = .;
+  _rodata_size = . - _rodata;
+  _rodata_vsize = _evrodata - _rodata;
   _alldata_size = . - _data;
 
-  . = ALIGN(4096);
-  .dynsym   : { *(.dynsym) }
-  . = ALIGN(4096);
-  .dynstr   : { *(.dynstr) }
-  . = ALIGN(4096);
   /DISCARD/ :
   {
     *(.rel.reloc)
index 362bd1f8238e67a05032e9d971b603bbb7c06b75..fd1d123d85144b30ff12501eeba99c54b0f07a20 100755 (executable)
@@ -92,7 +92,7 @@ endif
 #
 # Where to build the package
 #
-OBJDIR       := $(TOPDIR)/$(ARCH)
+OBJDIR       := $(abspath .)/$(ARCH)
 
 #
 # Variables below derived from variables above
index b41b8e76ffde14282151fd3a2d47cebf57f7625e..a96b5eb8df462b6f3a4c3295169f08a567d9407c 100644 (file)
@@ -31,7 +31,7 @@ pe_header:
        .short  0
 coff_header:
        .short  0xaa64                          // AArch64
-       .short  3                               // nr_sections
+       .short  4                               // nr_sections
        .long   0                               // TimeDateStamp
        .long   0                               // PointerToSymbolTable
        .long   1                               // NumberOfSymbols
@@ -44,7 +44,7 @@ optional_header:
        .short  0x20b                           // PE32+ format
        .byte   0x02                            // MajorLinkerVersion
        .byte   0x14                            // MinorLinkerVersion
-       .long   _data - _start                  // SizeOfCode
+       .long   _text_size                      // SizeOfCode
        .long   _alldata_size                   // SizeOfInitializedData
        .long   0                               // SizeOfUninitializedData
        .long   _start - ImageBase              // AddressOfEntryPoint
@@ -62,7 +62,7 @@ extra_header_fields:
        .short  0                               // MinorSubsystemVersion
        .long   0                               // Win32VersionValue
 
-       .long   _esbat - ImageBase              // SizeOfImage
+       .long   _erodata - ImageBase            // SizeOfImage
 
        // Everything before the kernel image is considered part of the header
        .long   _start - ImageBase              // SizeOfHeaders
@@ -86,19 +86,22 @@ extra_header_fields:
        // Section table
 section_table:
        .ascii  ".text\0\0\0"
-       .long   _data - _start          // VirtualSize
+       .long   _evtext - _start        // VirtualSize
        .long   _start - ImageBase      // VirtualAddress
-       .long   _data - _start          // SizeOfRawData
+       .long   _etext - _start         // SizeOfRawData
        .long   _start - ImageBase      // PointerToRawData
 
        .long   0               // PointerToRelocations (0 for executables)
        .long   0               // PointerToLineNumbers (0 for executables)
        .short  0               // NumberOfRelocations  (0 for executables)
        .short  0               // NumberOfLineNumbers  (0 for executables)
+       /*
+        * EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_CNT_CODE
+        */
        .long   0x60000020      // Characteristics (section flags)
 
        .ascii  ".data\0\0\0"
-       .long   _data_size              // VirtualSize
+       .long   _data_vsize             // VirtualSize
        .long   _data - ImageBase       // VirtualAddress
        .long   _data_size              // SizeOfRawData
        .long   _data - ImageBase       // PointerToRawData
@@ -107,9 +110,12 @@ section_table:
        .long   0               // PointerToLineNumbers (0 for executables)
        .short  0               // NumberOfRelocations  (0 for executables)
        .short  0               // NumberOfLineNumbers  (0 for executables)
+       /*
+        * EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+        */
        .long   0xc0000040      // Characteristics (section flags)
 
-       .ascii  ".sbat\0\0\0"
+       .ascii  ".sbat\0\0\0"
        .long   _sbat_vsize             // VirtualSize
        .long   _sbat - ImageBase       // VirtualAddress
        .long   _sbat_size              // SizeOfRawData
@@ -119,6 +125,24 @@ section_table:
        .long   0               // PointerToLineNumbers (0 for executables)
        .short  0               // NumberOfRelocations  (0 for executables)
        .short  0               // NumberOfLineNumbers  (0 for executables)
+       /*
+        * EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_ALIGN_8BYTES | EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+        */
+       .long   0x40400040      // Characteristics (section flags)
+
+       .ascii  ".rodata\0"
+       .long   _rodata_vsize           // VirtualSize
+       .long   _rodata - ImageBase     // VirtualAddress
+       .long   _rodata_size            // SizeOfRawData
+       .long   _rodata - ImageBase     // PointerToRawData
+
+       .long   0               // PointerToRelocations (0 for executables)
+       .long   0               // PointerToLineNumbers (0 for executables)
+       .short  0               // NumberOfRelocations  (0 for executables)
+       .short  0               // NumberOfLineNumbers  (0 for executables)
+       /*
+        * EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_ALIGN_8BYTES | EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+        */
        .long   0x40400040      // Characteristics (section flags)
 
        .align          12
index 6401363cb85cc19076e39c3284f4b2aa452f2902..1efc21c351c71b9d93ade6d6b42a69385847d667 100644 (file)
@@ -31,7 +31,7 @@ pe_header:
        .short  0
 coff_header:
        .short  0x1c2                           // Mixed ARM/Thumb
-       .short  3                               // nr_sections
+       .short  4                               // nr_sections
        .long   0                               // TimeDateStamp
        .long   0                               // PointerToSymbolTable
        .long   1                               // NumberOfSymbols
@@ -45,17 +45,17 @@ optional_header:
        .short  0x10b                           // PE32+ format
        .byte   0x02                            // MajorLinkerVersion
        .byte   0x14                            // MinorLinkerVersion
-       .long   _data - _start                  // SizeOfCode
+       .long   _text_size                      // SizeOfCode
        .long   _alldata_size                   // SizeOfInitializedData
        .long   0                               // SizeOfUninitializedData
        .long   _start - ImageBase              // AddressOfEntryPoint
        .long   _start - ImageBase              // BaseOfCode
-       .long   0                               // BaseOfData
+       .long   _data - ImageBase               // BaseOfData
 
 extra_header_fields:
        .long   0                               // ImageBase
-       .long   0x20                            // SectionAlignment
-       .long   0x8                             // FileAlignment
+       .long   0x800                           // SectionAlignment
+       .long   0x200                           // FileAlignment
        .short  0                               // MajorOperatingSystemVersion
        .short  0                               // MinorOperatingSystemVersion
        .short  0                               // MajorImageVersion
@@ -64,7 +64,7 @@ extra_header_fields:
        .short  0                               // MinorSubsystemVersion
        .long   0                               // Win32VersionValue
 
-       .long   _esbat - ImageBase              // SizeOfImage
+       .long   _erodata - ImageBase            // SizeOfImage
 
        // Everything before the kernel image is considered part of the header
        .long   _start - ImageBase              // SizeOfHeaders
@@ -88,6 +88,7 @@ extra_header_fields:
        // Section table
 section_table:
 
+#if 0
        /*
         * The EFI application loader requires a relocation section
         * because EFI applications must be relocatable.  This is a
@@ -105,23 +106,37 @@ section_table:
        .short  0                       // NumberOfRelocations
        .short  0                       // NumberOfLineNumbers
        .long   0x42100040              // Characteristics (section flags)
+#endif
 
-
-       .ascii  ".text"
-       .byte   0
-       .byte   0
-       .byte   0                       // end of 0 padding of section name
-       .long   _edata - _start         // VirtualSize
+       .ascii  ".text\0\0\0"
+       .long   _evtext - _start        // VirtualSize
        .long   _start - ImageBase      // VirtualAddress
-       .long   _edata - _start         // SizeOfRawData
+       .long   _etext - _start         // SizeOfRawData
        .long   _start - ImageBase      // PointerToRawData
 
        .long   0               // PointerToRelocations (0 for executables)
        .long   0               // PointerToLineNumbers (0 for executables)
        .short  0               // NumberOfRelocations  (0 for executables)
        .short  0               // NumberOfLineNumbers  (0 for executables)
-       .long   0xe0500020      // Characteristics (section flags)
+       /*
+        * EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_CNT_CODE
+        */
+       .long   0x60000020      // Characteristics (section flags)
+
+       .ascii  ".data\0\0\0"
+       .long   _data_vsize             // VirtualSize
+       .long   _data - ImageBase       // VirtualAddress
+       .long   _data_size              // SizeOfRawData
+       .long   _data - ImageBase       // PointerToRawData
 
+       .long   0               // PointerToRelocations (0 for executables)
+       .long   0               // PointerToLineNumbers (0 for executables)
+       .short  0               // NumberOfRelocations  (0 for executables)
+       .short  0               // NumberOfLineNumbers  (0 for executables)
+       /*
+        * EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+        */
+       .long   0xc0000040      // Characteristics (section flags)
 
        .ascii  ".sbat\0\0\0"
        .long   _sbat_vsize             // VirtualSize
@@ -133,9 +148,28 @@ section_table:
        .long   0               // PointerToLineNumbers (0 for executables)
        .short  0               // NumberOfRelocations  (0 for executables)
        .short  0               // NumberOfLineNumbers  (0 for executables)
+       /*
+        * EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_ALIGN_8BYTES | EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+        */
+       .long   0x40400040      // Characteristics (section flags)
+
+       .ascii  ".rodata\0"
+       .long   _rodata_vsize           // VirtualSize
+       .long   _rodata - ImageBase     // VirtualAddress
+       .long   _rodata_size            // SizeOfRawData
+       .long   _rodata - ImageBase     // PointerToRawData
+
+       .long   0               // PointerToRelocations (0 for executables)
+       .long   0               // PointerToLineNumbers (0 for executables)
+       .short  0               // NumberOfRelocations  (0 for executables)
+       .short  0               // NumberOfLineNumbers  (0 for executables)
+       /*
+        * EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_ALIGN_8BYTES | EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+        */
        .long   0x40400040      // Characteristics (section flags)
 
 
+       .align 11
 _start:
        stmfd           sp!, {r0-r2, lr}
 
index 5db82379db8f2dfd80dfca1f5b464746be4b8aac..8551b74a273dc7d77a82c6732512c9ef7bc22ac3 100644 (file)
        (UEFI_VAR_NV_BS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
 
 #if defined(ENABLE_SHIM_DEVEL)
-#define SBAT_VAR_NAME L"SBAT_DEVEL"
-#define SBAT_VAR_NAME8 "SBAT_DEVEL"
-#define SBAT_RT_VAR_NAME L"SbatRT_DEVEL"
-#define SBAT_RT_VAR_NAME8 "SbatRT_DEVEL"
+#define SBAT_VAR_NAME L"SbatLevel_DEVEL"
+#define SBAT_VAR_NAME8 "SbatLevel_DEVEL"
+#define SBAT_RT_VAR_NAME L"SbatLevelRT_DEVEL"
+#define SBAT_RT_VAR_NAME8 "SbatLevelRT_DEVEL"
 #define SBAT_VAR_ATTRS UEFI_VAR_NV_BS_RT
 #else
-#define SBAT_VAR_NAME L"SBAT"
-#define SBAT_VAR_NAME8 "SBAT"
-#define SBAT_RT_VAR_NAME L"SbatRT"
-#define SBAT_RT_VAR_NAME8 "SbatRT"
+#define SBAT_VAR_NAME L"SbatLevel"
+#define SBAT_VAR_NAME8 "SbatLevel"
+#define SBAT_RT_VAR_NAME L"SbatLevelRT"
+#define SBAT_RT_VAR_NAME8 "SbatLevelRT"
 #define SBAT_VAR_ATTRS UEFI_VAR_NV_BS
 #endif
 
@@ -51,6 +51,7 @@ extern list_t sbat_var;
 EFI_STATUS parse_sbat_var(list_t *entries);
 void cleanup_sbat_var(list_t *entries);
 EFI_STATUS set_sbat_uefi_variable(void);
+bool preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize, UINT32 attributes);
 
 struct sbat_section_entry {
        const CHAR8 *component_name;
index 6d83f789a914aaca03a21d6ad1dad145a625ef71..a4a4855bce9b1c6619c68cbe21f1e0dc25370a26 100644 (file)
@@ -1,6 +1,6 @@
 TARGET = lib.a
 
-LIBFILES_UNSORTED := $(foreach x,$(wildcard *.c),$(patsubst %.c,%.o,$(x)))
+LIBFILES_UNSORTED := $(patsubst %.c,%.o,$(subst $(TOPDIR)/lib/,,$(wildcard $(TOPDIR)/lib/*.c)))
 LIBFILES := $(sort $(LIBFILES_UNSORTED))
 
 CRYPTDIR       = $(TOPDIR)/Cryptlib
diff --git a/pe.c b/pe.c
index 73b05a511ad47e6fe1e915ea9761b53311183ce0..365e32aa3bc04a092862eb84b8b7658bf1b8a83d 100644 (file)
--- a/pe.c
+++ b/pe.c
@@ -1054,6 +1054,8 @@ handle_image (void *data, unsigned int datasize,
                                SBATBase = base;
                                /* +1 because of size vs last byte location */
                                SBATSize = end - base + 1;
+                               dprint(L"sbat section base:0x%lx size:0x%lx\n",
+                                      SBATBase, SBATSize);
                        }
                }
 
diff --git a/sbat.c b/sbat.c
index 89c084178c9bb32c57ac62e0d528d0ad69c37958..6b7eb20a8b6e699ac7082945337af0e7fc4596f4 100644 (file)
--- a/sbat.c
+++ b/sbat.c
@@ -18,14 +18,20 @@ parse_sbat_section(char *section_base, size_t section_size,
        size_t n;
        char *strtab;
 
-       if (!section_base || !section_size || !n_entries || !entriesp)
+       if (!section_base || !section_size || !n_entries || !entriesp) {
+               dprint(L"section_base:0x%lx section_size:0x%lx\n",
+                      section_base, section_size);
+               dprint(L"n_entries:0x%lx entriesp:0x%lx\n",
+                      n_entries, entriesp);
                return EFI_INVALID_PARAMETER;
+       }
 
        INIT_LIST_HEAD(&csv);
 
        efi_status =
                parse_csv_data(section_base, end, SBAT_SECTION_COLUMNS, &csv);
        if (EFI_ERROR(efi_status)) {
+               dprint(L"parse_csv_data failed: %r\n", efi_status);
                return efi_status;
        }
 
@@ -38,6 +44,8 @@ parse_sbat_section(char *section_base, size_t section_size,
 
                if (row->n_columns < SBAT_SECTION_COLUMNS) {
                        efi_status = EFI_INVALID_PARAMETER;
+                       dprint(L"row->n_columns:%lu SBAT_SECTION_COLUMNS:%lu\n",
+                              row->n_columns, SBAT_SECTION_COLUMNS);
                        goto err;
                }
 
@@ -45,6 +53,7 @@ parse_sbat_section(char *section_base, size_t section_size,
                allocsz += sizeof(struct sbat_section_entry);
                for (i = 0; i < row->n_columns; i++) {
                        if (row->columns[i][0] == '\000') {
+                               dprint(L"row[%lu].columns[%lu][0] == '\\000'\n", n, i);
                                efi_status = EFI_INVALID_PARAMETER;
                                goto err;
                        }
@@ -120,8 +129,8 @@ verify_single_entry(struct sbat_section_entry *entry, struct sbat_var_entry *sba
                sbat_var_gen = atoi((const char *)sbat_var_entry->component_generation);
 
                if (sbat_gen < sbat_var_gen) {
-                       dprint(L"component %a, generation %d, was revoked by SBAT variable",
-                              entry->component_name, sbat_gen);
+                       dprint(L"component %a, generation %d, was revoked by %s variable\n",
+                              entry->component_name, sbat_gen, SBAT_VAR_NAME);
                        LogError(L"image did not pass SBAT verification\n");
                        return EFI_SECURITY_VIOLATION;
                }
@@ -139,7 +148,7 @@ cleanup_sbat_var(list_t *entries)
        list_for_each_safe(pos, tmp, entries) {
                entry = list_entry(pos, struct sbat_var_entry, list);
 
-               if ((uintptr_t)entry < (uintptr_t)first && entry != NULL)
+               if (first == NULL || (uintptr_t)entry < (uintptr_t)first)
                        first = entry;
 
                list_del(&entry->list);
@@ -157,7 +166,7 @@ verify_sbat_helper(list_t *local_sbat_var, size_t n, struct sbat_section_entry *
        struct sbat_var_entry *sbat_var_entry;
 
        if (list_empty(local_sbat_var)) {
-               dprint(L"SBAT variable not present\n");
+               dprint(L"%s variable not present\n", SBAT_VAR_NAME);
                return EFI_SUCCESS;
        }
 
@@ -239,10 +248,10 @@ parse_sbat_var_data(list_t *entry_list, UINT8 *data, UINTN datasize)
 
        INIT_LIST_HEAD(entry_list);
 
-       entries = (struct sbat_var_entry **)strtab;
-       strtab += sizeof(struct sbat_var_entry *) * n;
        entry = (struct sbat_var_entry *)strtab;
        strtab += sizeof(struct sbat_var_entry) * n;
+       entries = (struct sbat_var_entry **)strtab;
+       strtab += sizeof(struct sbat_var_entry *) * n;
        n = 0;
 
        list_for_each(pos, &csv) {
@@ -277,8 +286,10 @@ parse_sbat_var(list_t *entries)
        UINTN datasize;
        EFI_STATUS efi_status;
 
-       if (!entries)
+       if (!entries) {
+               dprint(L"entries is NULL\n");
                return EFI_INVALID_PARAMETER;
+       }
 
        efi_status = get_variable(SBAT_VAR_NAME, &data, &datasize, SHIM_LOCK_GUID);
        if (EFI_ERROR(efi_status)) {
@@ -304,6 +315,14 @@ check_sbat_var_attributes(UINT32 attributes)
 #endif
 }
 
+bool
+preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize, UINT32 attributes)
+{
+       return check_sbat_var_attributes(attributes) &&
+              sbatsize >= strlen(SBAT_VAR_SIG "1") &&
+              !strncmp((const char *)sbat, SBAT_VAR_SIG, strlen(SBAT_VAR_SIG));
+}
+
 EFI_STATUS
 set_sbat_uefi_variable(void)
 {
@@ -316,19 +335,16 @@ set_sbat_uefi_variable(void)
        efi_status = get_variable_attr(SBAT_VAR_NAME, &sbat, &sbatsize,
                                       SHIM_LOCK_GUID, &attributes);
        /*
-        * Always set the SBAT UEFI variable if it fails to read.
+        * Always set the SbatLevel UEFI variable if it fails to read.
         *
-        * Don't try to set the SBAT UEFI variable if attributes match and
-        * the signature matches.
+        * Don't try to set the SbatLevel UEFI variable if attributes match
+        * and the signature matches.
         */
        if (EFI_ERROR(efi_status)) {
                dprint(L"SBAT read failed %r\n", efi_status);
-       } else if (check_sbat_var_attributes(attributes) &&
-                  sbatsize >= strlen(SBAT_VAR_SIG "1") &&
-                  strncmp((const char *)sbat, SBAT_VAR_SIG,
-                          strlen(SBAT_VAR_SIG))) {
-               dprint("SBAT variable is %d bytes, attributes are 0x%08x\n",
-                      sbatsize, attributes);
+       } else if (preserve_sbat_uefi_variable(sbat, sbatsize, attributes)) {
+               dprint(L"%s variable is %d bytes, attributes are 0x%08x\n",
+                      SBAT_VAR_NAME, sbatsize, attributes);
                FreePool(sbat);
                return EFI_SUCCESS;
        } else {
@@ -341,7 +357,8 @@ set_sbat_uefi_variable(void)
                efi_status = set_variable(SBAT_VAR_NAME, SHIM_LOCK_GUID,
                                          attributes, 0, "");
                if (EFI_ERROR(efi_status)) {
-                       dprint(L"SBAT variable delete failed %r\n", efi_status);
+                       dprint(L"%s variable delete failed %r\n", SBAT_VAR_NAME,
+                                       efi_status);
                        return efi_status;
                }
        }
@@ -350,7 +367,8 @@ set_sbat_uefi_variable(void)
        efi_status = set_variable(SBAT_VAR_NAME, SHIM_LOCK_GUID, SBAT_VAR_ATTRS,
                                  sizeof(SBAT_VAR)-1, SBAT_VAR);
        if (EFI_ERROR(efi_status)) {
-               dprint(L"SBAT variable writing failed %r\n", efi_status);
+               dprint(L"%s variable writing failed %r\n", SBAT_VAR_NAME,
+                               efi_status);
                return efi_status;
        }
 
@@ -358,7 +376,7 @@ set_sbat_uefi_variable(void)
        efi_status = get_variable(SBAT_VAR_NAME, &sbat, &sbatsize,
                                  SHIM_LOCK_GUID);
        if (EFI_ERROR(efi_status)) {
-               dprint(L"SBAT read failed %r\n", efi_status);
+               dprint(L"%s read failed %r\n", SBAT_VAR_NAME, efi_status);
                return efi_status;
        }
 
@@ -368,7 +386,7 @@ set_sbat_uefi_variable(void)
                       strlen(SBAT_VAR));
                efi_status = EFI_INVALID_PARAMETER;
        } else {
-               dprint(L"SBAT variable initialization succeeded\n");
+               dprint(L"%s variable initialization succeeded\n", SBAT_VAR_NAME);
        }
 
        FreePool(sbat);
diff --git a/shim.c b/shim.c
index 117c8f42421f91423b8d6b9189506feb6c4b1e5f..c5cfbb830d72e974b3a4c3730568d1fb1b5e82cc 100644 (file)
--- a/shim.c
+++ b/shim.c
@@ -1895,7 +1895,7 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
                L"shim_init() failed",
                L"import of SBAT data failed",
                L"SBAT self-check failed",
-               L"SBAT UEFI variable setting failed",
+               SBAT_VAR_NAME L" UEFI variable setting failed",
                NULL
        };
        enum {
@@ -1935,12 +1935,12 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
 
        efi_status = set_sbat_uefi_variable();
        if (EFI_ERROR(efi_status) && secure_mode()) {
-               perror(L"SBAT variable initialization failed\n");
+               perror(L"%s variable initialization failed\n", SBAT_VAR_NAME);
                msg = SET_SBAT;
                goto die;
        } else if (EFI_ERROR(efi_status)) {
-               dprint(L"SBAT variable initialization failed: %r\n",
-                      efi_status);
+               dprint(L"%s variable initialization failed: %r\n",
+                      SBAT_VAR_NAME, efi_status);
        }
 
        if (secure_mode()) {
@@ -1950,19 +1950,20 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
                INIT_LIST_HEAD(&sbat_var);
                efi_status = parse_sbat_var(&sbat_var);
                if (EFI_ERROR(efi_status)) {
-                       perror(L"Parsing SBAT variable failed: %r\n",
-                               efi_status);
+                       perror(L"Parsing %s variable failed: %r\n",
+                               SBAT_VAR_NAME, efi_status);
                        msg = IMPORT_SBAT;
                        goto die;
                }
 
-               efi_status = handle_sbat(sbat_start, sbat_end - sbat_start);
+               efi_status = handle_sbat(sbat_start, sbat_end - sbat_start - 1);
                if (EFI_ERROR(efi_status)) {
                        perror(L"Verifiying shim SBAT data failed: %r\n",
                               efi_status);
                        msg = SBAT_SELF_CHECK;
                        goto die;
                }
+               dprint(L"SBAT self-check succeeded\n");
        }
 
        init_openssl();
index 780e5cbe41ac7494256fea9af2a0a8b8aaa36629..b64aa1e90452c8aae2b1231a40516ba6979aac64 100644 (file)
@@ -319,6 +319,7 @@ test_parse_sbat_section_too_many_elem(void)
        struct sbat_section_entry *test_entries[] = {
                &test_section_entry1, &test_section_entry2,
        };
+       int rc = -1;
 
        status = parse_sbat_section(section_base, section_size, &n, &entries);
        assert_equal_return(status, EFI_SUCCESS, -1, "got %#hhx expected %#hhx\n");
@@ -341,10 +342,10 @@ test_parse_sbat_section_too_many_elem(void)
 #undef mkassert
        }
        assert_equal_goto(n, 2, fail, "got %zu expected %d\n");
-       return 0;
+       rc = 0;
 fail:
        cleanup_sbat_section_entries(n, entries);
-       return -1;
+       return rc;
 }
 
 /*
@@ -439,14 +440,19 @@ test_verify_sbat_null_sbat_section(void)
        list_t test_sbat_var;
        size_t n = 0;
        struct sbat_section_entry **entries = NULL;
+       int rc = -1;
 
        INIT_LIST_HEAD(&test_sbat_var);
        status = parse_sbat_var_data(&test_sbat_var, sbat_var_data, sizeof(sbat_var_data));
-       assert_equal_return(status, EFI_SUCCESS, -1, "got %#x expected %#x\n");
+       assert_equal_goto(status, EFI_SUCCESS, err, "got %#x expected %#x\n");
 
-       status = verify_sbat_helper(&sbat_var, n, entries);
-       assert_equal_return(status, EFI_SUCCESS, -1, "got %#x expected %#x\n");
-       return 0;
+       status = verify_sbat_helper(&test_sbat_var, n, entries);
+       assert_equal_goto(status, EFI_SUCCESS, err, "got %#x expected %#x\n");
+       rc = 0;
+err:
+       cleanup_sbat_var(&test_sbat_var);
+
+       return rc;
 }
 
 #if 0
@@ -902,6 +908,7 @@ test_parse_and_verify(void)
        struct sbat_section_entry *test_entries[] = {
                &test_section_entry1, &test_section_entry2,
        };
+       int rc = -1;
 
        status = parse_sbat_section(sbat_section, sizeof(sbat_section)-1,
                                    &n_section_entries, &section_entries);
@@ -940,16 +947,71 @@ test_parse_and_verify(void)
 
        INIT_LIST_HEAD(&sbat_var);
        status = parse_sbat_var_data(&sbat_var, sbat_var_alloced, sbat_var_data_size);
+       free(sbat_var_alloced);
        if (status != EFI_SUCCESS || list_empty(&sbat_var))
                return -1;
 
        status = verify_sbat(n_section_entries, section_entries);
+       assert_equal_goto(status, EFI_SECURITY_VIOLATION, err, "expected %#x got %#x\n");
 
-       assert_equal_return(status, EFI_SECURITY_VIOLATION, -1, "expected %#x got %#x\n");
-       cleanup_sbat_var(&sbat_var);
+       rc = 0;
+err:
        cleanup_sbat_section_entries(n_section_entries, section_entries);
+       cleanup_sbat_var(&sbat_var);
 
-       return 0;
+       return rc;
+}
+
+int
+test_preserve_sbat_uefi_variable_good(void)
+{
+       char sbat[] = "sbat,1,\ncomponent,2,\n";
+       size_t sbat_size = sizeof(sbat);
+       UINT32 attributes = SBAT_VAR_ATTRS;
+
+       if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+               return 0;
+       else
+               return -1;
+}
+
+int
+test_preserve_sbat_uefi_variable_bad_sig(void)
+{
+       char sbat[] = "bad_sig,1,\ncomponent,2,\n";
+       size_t sbat_size = sizeof(sbat);
+       UINT32 attributes = SBAT_VAR_ATTRS;
+
+       if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+               return -1;
+       else
+               return 0;
+}
+
+int
+test_preserve_sbat_uefi_variable_bad_attr(void)
+{
+       char sbat[] = "sbat,1,\ncomponent,2,\n";
+       size_t sbat_size = sizeof(sbat);
+       UINT32 attributes = 0;
+
+       if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+               return -1;
+       else
+               return 0;
+}
+
+int
+test_preserve_sbat_uefi_variable_bad_short(void)
+{
+       char sbat[] = "sba";
+       size_t sbat_size = sizeof(sbat);
+       UINT32 attributes = SBAT_VAR_ATTRS;
+
+       if (preserve_sbat_uefi_variable(sbat, sbat_size, attributes))
+               return -1;
+       else
+               return 0;
 }
 
 int
@@ -989,6 +1051,11 @@ main(void)
 #endif
        test(test_parse_and_verify);
 
+       test(test_preserve_sbat_uefi_variable_good);
+       test(test_preserve_sbat_uefi_variable_bad_sig);
+       test(test_preserve_sbat_uefi_variable_bad_attr);
+       test(test_preserve_sbat_uefi_variable_bad_short);
+
        return 0;
 }