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
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
# load the local configuration if it exists
-include Make.local
+-include $(TOPDIR)/Make.local
COMPILER ?= gcc
CC = $(CROSS_COMPILE)$(COMPILER)
default : all
NAME = shim
-VERSION = 15.3
+VERSION = 15.4
ifneq ($(origin RELEASE),undefined)
DASHRELEASE ?= -$(RELEASE)
else
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)
$(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
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
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
$(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) $< $@
$(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 \
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)
-630b8dedfd8434353bce80ff89f63fd3113b086d
\ No newline at end of file
+20e4d9486fcae54ee44d2323ae342ffe68c920e6
\ No newline at end of file
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);
*(.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 :
*(.got.plt)
*(.got)
+ *(.dynamic)
+
/* the EFI loader doesn't seem to like a .bss section, so we stick
it all into .data: */
. = ALIGN(16);
*(.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)
*(.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 :
*(.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);
*(.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)
#
# Where to build the package
#
-OBJDIR := $(TOPDIR)/$(ARCH)
+OBJDIR := $(abspath .)/$(ARCH)
#
# Variables below derived from variables above
.short 0
coff_header:
.short 0xaa64 // AArch64
- .short 3 // nr_sections
+ .short 4 // nr_sections
.long 0 // TimeDateStamp
.long 0 // PointerToSymbolTable
.long 1 // NumberOfSymbols
.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
.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
// 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
.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
.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
.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
.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
.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
// Section table
section_table:
+#if 0
/*
* The EFI application loader requires a relocation section
* because EFI applications must be relocatable. This is a
.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
.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}
(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
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;
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
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);
}
}
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;
}
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;
}
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;
}
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;
}
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);
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;
}
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) {
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)) {
#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)
{
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 {
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;
}
}
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;
}
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;
}
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);
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 {
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()) {
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();
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");
#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;
}
/*
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
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, §ion_entries);
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
#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;
}