mirror of
https://git.proxmox.com/git/efi-boot-shim
synced 2025-08-06 00:23:05 +00:00
New upstream version 15.8
This commit is contained in:
parent
2dd2f7600d
commit
a075e58606
8
.github/workflows/pullrequest.yml
vendored
8
.github/workflows/pullrequest.yml
vendored
@ -135,10 +135,6 @@ jobs:
|
||||
efiarch: x64
|
||||
makearch: x86_64
|
||||
distro: centos8
|
||||
- arch: amd64
|
||||
efiarch: x64
|
||||
makearch: x86_64
|
||||
distro: centos7
|
||||
- arch: amd64
|
||||
efiarch: ia32
|
||||
makearch: ia32
|
||||
@ -155,10 +151,6 @@ jobs:
|
||||
efiarch: ia32
|
||||
makearch: ia32
|
||||
distro: centos8
|
||||
- arch: amd64
|
||||
efiarch: ia32
|
||||
makearch: ia32
|
||||
distro: centos7
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -33,7 +33,12 @@ Make.local
|
||||
/.cache/
|
||||
/certdb/
|
||||
/compile_commands.json
|
||||
/compile_commands.events.json
|
||||
/cov-int/
|
||||
/crash-*
|
||||
/fuzz-*
|
||||
!/fuzz-*.c
|
||||
/leak-*
|
||||
/post-process-pe
|
||||
/random.bin
|
||||
/sbat.*.csv
|
||||
|
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,4 +1,4 @@
|
||||
[submodule "gnu-efi"]
|
||||
path = gnu-efi
|
||||
url = https://github.com/rhboot/gnu-efi.git
|
||||
branch = shim-15.6
|
||||
branch = shim-15.8
|
||||
|
3
BUILDING
3
BUILDING
@ -78,6 +78,9 @@ Variables you could set to customize the build:
|
||||
- OSLABEL
|
||||
This is the label that will be put in BOOT$(EFI_ARCH).CSV for your OS.
|
||||
By default this is the same value as EFIDIR .
|
||||
- POST_PROCESS_PE_FLAGS
|
||||
This allows you to add flags to the invocation of "post-process-pe", for
|
||||
example to disable the NX compatibility flag.
|
||||
|
||||
Vendor SBAT data:
|
||||
It will sometimes be requested by reviewers that a build includes extra
|
||||
|
@ -11,7 +11,8 @@ INCLUDES = -I$(CRYPTDIR) -I$(CRYPTDIR)/Include \
|
||||
-isystem $(TOPDIR)/include/system \
|
||||
-isystem $(shell $(CC) -print-file-name=include)
|
||||
|
||||
WARNFLAGS += -Wno-unused-parameter
|
||||
WARNFLAGS += -Wno-unused-parameter \
|
||||
-Wno-unused-but-set-variable
|
||||
|
||||
CFLAGS = $(FEATUREFLAGS) \
|
||||
$(OPTIMIZATIONS) \
|
||||
|
@ -23,7 +23,7 @@ FEATUREFLAGS += -nostdinc
|
||||
WARNFLAGS += -Wno-empty-body \
|
||||
-Wno-implicit-fallthrough \
|
||||
$(if $(findstring gcc,$(CC)),-Wno-old-style-declaration) \
|
||||
$(if $(findstring gcc,$(CC)),-Wno-unused-but-set-variable) \
|
||||
-Wno-unused-but-set-variable \
|
||||
-Wno-unused-parameter
|
||||
|
||||
CFLAGS = $(FEATUREFLAGS) \
|
||||
|
@ -15,6 +15,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include <OpenSslSupport.h>
|
||||
|
||||
//
|
||||
// Extra header to record the memory buffer size from malloc routine.
|
||||
//
|
||||
#define CRYPTMEM_HEAD_SIGNATURE EFI_SIGNATURE_32('c','m','h','d')
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
UINT32 Reserved;
|
||||
UINTN Size;
|
||||
} CRYPTMEM_HEAD;
|
||||
|
||||
#define CRYPTMEM_OVERHEAD sizeof(CRYPTMEM_HEAD)
|
||||
|
||||
#define MIN(a, b) ({(a) < (b) ? (a) : (b);})
|
||||
|
||||
//
|
||||
// -- Memory-Allocation Routines --
|
||||
//
|
||||
@ -22,27 +36,84 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
/* Allocates memory blocks */
|
||||
void *malloc (size_t size)
|
||||
{
|
||||
return AllocatePool ((UINTN) size);
|
||||
CRYPTMEM_HEAD *PoolHdr;
|
||||
UINTN NewSize;
|
||||
VOID *Data;
|
||||
|
||||
//
|
||||
// Adjust the size by the buffer header overhead
|
||||
//
|
||||
NewSize = (UINTN)(size) + CRYPTMEM_OVERHEAD;
|
||||
|
||||
Data = AllocatePool (NewSize);
|
||||
if (Data != NULL) {
|
||||
PoolHdr = (CRYPTMEM_HEAD *)Data;
|
||||
//
|
||||
// Record the memory brief information
|
||||
//
|
||||
PoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE;
|
||||
PoolHdr->Size = size;
|
||||
|
||||
return (VOID *)(PoolHdr + 1);
|
||||
} else {
|
||||
//
|
||||
// The buffer allocation failed.
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reallocate memory blocks */
|
||||
void *realloc (void *ptr, size_t size)
|
||||
{
|
||||
//
|
||||
// BUG: hardcode OldSize == size! We have no any knowledge about
|
||||
// memory size of original pointer ptr.
|
||||
//
|
||||
return ReallocatePool (ptr, (UINTN) size, (UINTN) size);
|
||||
CRYPTMEM_HEAD *OldPoolHdr;
|
||||
CRYPTMEM_HEAD *NewPoolHdr;
|
||||
UINTN OldSize;
|
||||
UINTN NewSize;
|
||||
VOID *Data;
|
||||
|
||||
NewSize = (UINTN)size + CRYPTMEM_OVERHEAD;
|
||||
Data = AllocatePool (NewSize);
|
||||
if (Data != NULL) {
|
||||
NewPoolHdr = (CRYPTMEM_HEAD *)Data;
|
||||
NewPoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE;
|
||||
NewPoolHdr->Size = size;
|
||||
if (ptr != NULL) {
|
||||
//
|
||||
// Retrieve the original size from the buffer header.
|
||||
//
|
||||
OldPoolHdr = (CRYPTMEM_HEAD *)ptr - 1;
|
||||
ASSERT (OldPoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE);
|
||||
OldSize = OldPoolHdr->Size;
|
||||
|
||||
//
|
||||
// Duplicate the buffer content.
|
||||
//
|
||||
CopyMem ((VOID *)(NewPoolHdr + 1), ptr, MIN (OldSize, size));
|
||||
FreePool ((VOID *)OldPoolHdr);
|
||||
}
|
||||
|
||||
return (VOID *)(NewPoolHdr + 1);
|
||||
} else {
|
||||
//
|
||||
// The buffer allocation failed.
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* De-allocates or frees a memory block */
|
||||
void free (void *ptr)
|
||||
{
|
||||
CRYPTMEM_HEAD *PoolHdr;
|
||||
|
||||
//
|
||||
// In Standard C, free() handles a null pointer argument transparently. This
|
||||
// is not true of FreePool() below, so protect it.
|
||||
//
|
||||
if (ptr != NULL) {
|
||||
FreePool (ptr);
|
||||
PoolHdr = (CRYPTMEM_HEAD *)ptr - 1;
|
||||
ASSERT (PoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE);
|
||||
FreePool (PoolHdr);
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +139,8 @@ CFLAGS = $(FEATUREFLAGS) \
|
||||
$(INCLUDES) \
|
||||
$(DEFINES)
|
||||
|
||||
POST_PROCESS_PE_FLAGS =
|
||||
|
||||
ifneq ($(origin OVERRIDE_SECURITY_POLICY), undefined)
|
||||
DEFINES += -DOVERRIDE_SECURITY_POLICY
|
||||
endif
|
||||
@ -186,6 +188,9 @@ endif
|
||||
ifneq ($(origin VENDOR_DBX_FILE), undefined)
|
||||
DEFINES += -DVENDOR_DBX_FILE=\"$(VENDOR_DBX_FILE)\"
|
||||
endif
|
||||
ifneq ($(origin SBAT_AUTOMATIC_DATE), undefined)
|
||||
DEFINES += -DSBAT_AUTOMATIC_DATE=$(SBAT_AUTOMATIC_DATE)
|
||||
endif
|
||||
|
||||
LDFLAGS = --hash-style=sysv -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(LOCAL_EFI_PATH) -L$(LIBDIR) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) --build-id=sha1 $(ARCH_LDFLAGS) --no-undefined
|
||||
|
||||
|
@ -36,6 +36,6 @@ $(strip $(foreach x,$(DEFAULT_$(1)),
|
||||
endef
|
||||
|
||||
%.o : %.S
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
$(CC) $(CFLAGS) -c -o $@ $< $(IGNORE_COMPILER_ERRORS)
|
||||
|
||||
# vim:filetype=make
|
||||
|
45
Makefile
45
Makefile
@ -1,7 +1,7 @@
|
||||
default : all
|
||||
|
||||
NAME = shim
|
||||
VERSION = 15.7
|
||||
VERSION = 15.8
|
||||
ifneq ($(origin RELEASE),undefined)
|
||||
DASHRELEASE ?= -$(RELEASE)
|
||||
else
|
||||
@ -38,9 +38,9 @@ CFLAGS += -DENABLE_SHIM_CERT
|
||||
else
|
||||
TARGETS += $(MMNAME) $(FBNAME)
|
||||
endif
|
||||
OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o httpboot.o csv.o load-options.o
|
||||
OBJS = shim.o globals.o mok.o netboot.o cert.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o pe-relocate.o httpboot.o csv.o load-options.o
|
||||
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
|
||||
ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S
|
||||
ORIG_SOURCES = shim.c globals.c mok.c netboot.c replacements.c tpm.c errlog.c sbat.c pe.c pe-relocate.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S
|
||||
MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.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 globals.o
|
||||
@ -76,6 +76,13 @@ ifneq ($(origin EFI_PATH),undefined)
|
||||
$(error EFI_PATH is no longer supported, you must build using the supplied copy of gnu-efi)
|
||||
endif
|
||||
|
||||
compile_commands.json : Makefile Make.rules Make.defaults
|
||||
make clean
|
||||
bear -- make COMPILER=clang test all
|
||||
sed -i \
|
||||
-e 's/"-maccumulate-outgoing-args",//g' \
|
||||
$@
|
||||
|
||||
update :
|
||||
git submodule update --init --recursive
|
||||
|
||||
@ -156,19 +163,19 @@ gnu-efi/$(ARCH_GNUEFI)/gnuefi/libgnuefi.a gnu-efi/$(ARCH_GNUEFI)/lib/libefi.a:
|
||||
ARCH=$(ARCH_GNUEFI) \
|
||||
TOPDIR=$(TOPDIR)/gnu-efi \
|
||||
-f $(TOPDIR)/gnu-efi/Makefile \
|
||||
lib gnuefi inc
|
||||
lib gnuefi inc $(IGNORE_COMPILER_ERRORS)
|
||||
|
||||
Cryptlib/libcryptlib.a:
|
||||
for i in Hash Hmac Cipher Rand Pk Pem SysCall; do mkdir -p Cryptlib/$$i; done
|
||||
$(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile
|
||||
$(MAKE) TOPDIR=$(TOPDIR) VPATH=$(TOPDIR)/Cryptlib -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile $(IGNORE_COMPILER_ERRORS)
|
||||
|
||||
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) TOPDIR=$(TOPDIR) 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 $(IGNORE_COMPILER_ERRORS)
|
||||
|
||||
lib/lib.a: | $(TOPDIR)/lib/Makefile $(wildcard $(TOPDIR)/include/*.[ch])
|
||||
mkdir -p lib
|
||||
$(MAKE) VPATH=$(TOPDIR)/lib TOPDIR=$(TOPDIR) -C lib -f $(TOPDIR)/lib/Makefile
|
||||
$(MAKE) VPATH=$(TOPDIR)/lib TOPDIR=$(TOPDIR) -C lib -f $(TOPDIR)/lib/Makefile $(IGNORE_COMPILER_ERRORS)
|
||||
|
||||
post-process-pe : $(TOPDIR)/post-process-pe.c
|
||||
$(HOSTCC) -std=gnu11 -Og -g3 -Wall -Wextra -Wno-missing-field-initializers -Werror -o $@ $<
|
||||
@ -255,7 +262,7 @@ endif
|
||||
-j .rela* -j .dyn -j .reloc -j .eh_frame \
|
||||
-j .vendor_cert -j .sbat -j .sbatlevel \
|
||||
$(FORMAT) $< $@
|
||||
./post-process-pe -vv $@
|
||||
./post-process-pe -vv $(POST_PROCESS_PE_FLAGS) $@
|
||||
|
||||
ifneq ($(origin ENABLE_SHIM_HASH),undefined)
|
||||
%.hash : %.efi
|
||||
@ -286,6 +293,15 @@ else
|
||||
$(PESIGN) -n certdb -i $< -c "shim" -s -o $@ -f
|
||||
endif
|
||||
|
||||
fuzz fuzz-clean fuzz-coverage fuzz-lto :
|
||||
@make -f $(TOPDIR)/include/fuzz.mk \
|
||||
COMPILER="$(COMPILER)" \
|
||||
CROSS_COMPILE="$(CROSS_COMPILE)" \
|
||||
CLANG_WARNINGS="$(CLANG_WARNINGS)" \
|
||||
ARCH_DEFINES="$(ARCH_DEFINES)" \
|
||||
EFI_INCLUDES="$(EFI_INCLUDES)" \
|
||||
fuzz-clean $@
|
||||
|
||||
test test-clean test-coverage test-lto :
|
||||
@make -f $(TOPDIR)/include/test.mk \
|
||||
COMPILER="$(COMPILER)" \
|
||||
@ -295,14 +311,21 @@ test test-clean test-coverage test-lto :
|
||||
EFI_INCLUDES="$(EFI_INCLUDES)" \
|
||||
test-clean $@
|
||||
|
||||
$(patsubst %.c,%,$(wildcard fuzz-*.c)) :
|
||||
@make -f $(TOPDIR)/include/fuzz.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" $@
|
||||
|
||||
$(patsubst %.c,%,$(wildcard test-*.c)) :
|
||||
@make -f $(TOPDIR)/include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" $@
|
||||
|
||||
.PHONY : $(patsubst %.c,%,$(wildcard test-*.c)) test
|
||||
clean-fuzz-objs:
|
||||
@make -f $(TOPDIR)/include/fuzz.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" clean
|
||||
|
||||
clean-test-objs:
|
||||
@make -f $(TOPDIR)/include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" clean
|
||||
|
||||
.PHONY : $(patsubst %.c,%,$(wildcard fuzz-*.c)) fuzz
|
||||
.PHONY : $(patsubst %.c,%,$(wildcard test-*.c)) test
|
||||
|
||||
clean-gnu-efi:
|
||||
@if [ -d gnu-efi ] ; then \
|
||||
$(MAKE) -C gnu-efi \
|
||||
@ -322,7 +345,7 @@ clean-lib-objs:
|
||||
|
||||
clean-shim-objs:
|
||||
@rm -rvf $(TARGET) *.o $(SHIM_OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb $(BOOTCSVNAME)
|
||||
@rm -vf *.debug *.so *.efi *.efi.* *.tar.* version.c buildid post-process-pe
|
||||
@rm -vf *.debug *.so *.efi *.efi.* *.tar.* version.c buildid post-process-pe compile_commands.json
|
||||
@rm -vf Cryptlib/*.[oa] Cryptlib/*/*.[oa]
|
||||
@if [ -d .git ] ; then git clean -f -d -e 'Cryptlib/OpenSSL/*'; fi
|
||||
|
||||
@ -336,7 +359,7 @@ clean-cryptlib-objs:
|
||||
$(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-lib-objs
|
||||
clean: clean-shim-objs clean-fuzz-objs clean-test-objs clean-gnu-efi clean-openssl-objs clean-cryptlib-objs clean-lib-objs
|
||||
|
||||
GITTAG = $(VERSION)
|
||||
|
||||
|
@ -53,6 +53,11 @@ The hash will be regenerated by MokManager after the user is requested
|
||||
to enter their password to confirm enrolment of the keys. If the hash
|
||||
matches MokAuth, the user will be prompted to enrol the keys. BS,RT,NV
|
||||
|
||||
ShimRetainProtocol: UINT8, read by Shim before uninstalling protocol.
|
||||
If set to non-zero, Shim will keep the protocol in place. It can be
|
||||
used by second stages to ensure the protocol is still available for
|
||||
later stages, and can thus be used to verify additional PE files. BS,RT.
|
||||
|
||||
State variables:
|
||||
|
||||
MokList: A list of authorized keys and hashes. An EFI_SIGNATURE_LIST
|
||||
|
@ -25,3 +25,8 @@ There are a couple of build options, and a couple of ways to customize the
|
||||
build, described in [BUILDING](BUILDING).
|
||||
|
||||
See the [test plan](testplan.txt), and file a ticket if anything fails!
|
||||
|
||||
In the event that the developers need to be contacted related to a security
|
||||
incident or vulnerability, please mail [secalert@redhat.com].
|
||||
|
||||
[secalert@redhat.com]: mailto:secalert@redhat.com
|
||||
|
@ -5,14 +5,14 @@ SBAT: Current proposal
|
||||
-------------
|
||||
|
||||
the `.sbat` section has the following fields:
|
||||
| field | meaning |
|
||||
|---|---|
|
||||
| component_name | the name we're comparing
|
||||
| component_generation | the generation number for the comparison
|
||||
| vendor_name | human readable vendor name
|
||||
| vendor_package_name | human readable package name
|
||||
| vendor_version | human readable package version (maybe machine parseable too, not specified here)
|
||||
| vendor_url | url to look stuff up, contact, whatever.
|
||||
| field | meaning |
|
||||
|----------------------|----------------------------------------------------------------------------------|
|
||||
| component_name | the name we're comparing |
|
||||
| component_generation | the generation number for the comparison |
|
||||
| vendor_name | human readable vendor name |
|
||||
| vendor_package_name | human readable package name |
|
||||
| vendor_version | human readable package version (maybe machine parseable too, not specified here) |
|
||||
| vendor_url | url to look stuff up, contact, whatever. |
|
||||
|
||||
`SBAT` EFI variable
|
||||
-----------------
|
||||
|
30
SBAT.md
30
SBAT.md
@ -255,11 +255,11 @@ customer impact with as few re-releases as possible, while not creating an
|
||||
unnecessarily large UEFI revocation variable payload.
|
||||
|
||||
| | prior to<br>disclosure\* | after<br>disclosure | after Vendor C's<br>first update | after Vendor C's<br>second update | after next global<br>disclosure |
|
||||
|--------------------------------------------------------------------------------------|------------------------|---------------------|----------------------------------|----------------------------------|---------------------------------|
|
||||
| GRUB global<br>generation number in<br>artifacts .sbat section | 3 | 4 | 4 | 4 | 5 |
|
||||
| Vendor C's product-specific<br>generation number in artifact's<br>.sbat section | 1 | 1 | 2 | 3 | 1 |
|
||||
| GRUB global<br>generation number in<br>UEFI SBAT revocation variable | 3 | 4 | 4 | 4 | 5 |
|
||||
| Vendor C's product-specific<br>generation number in<br>UEFI SBAT revocation variable | not set | not set | 2 | 3 | not set |
|
||||
|--------------------------------------------------------------------------------------|--------------------------|---------------------|----------------------------------|-----------------------------------|---------------------------------|
|
||||
| GRUB global<br>generation number in<br>artifacts .sbat section | 3 | 4 | 4 | 4 | 5 |
|
||||
| Vendor C's product-specific<br>generation number in artifact's<br>.sbat section | 1 | 1 | 2 | 3 | 1 |
|
||||
| GRUB global<br>generation number in<br>UEFI SBAT revocation variable | 3 | 4 | 4 | 4 | 5 |
|
||||
| Vendor C's product-specific<br>generation number in<br>UEFI SBAT revocation variable | not set | not set | 2 | 3 | not set |
|
||||
|
||||
\* A disclosure is the event/date where a CVE and fixes for it are made public.
|
||||
|
||||
@ -307,7 +307,7 @@ most up to date UEFI metadata.
|
||||
Even prior to or without moving to one-shim, it is desirable to get every
|
||||
vendor onto as few shims as possible. Ideally a vendor would have a single shim
|
||||
signed with their certificate embedded and then use that certificate to sign
|
||||
additional <Vendor>_key.EFI key files that then contain all the keys that the
|
||||
additional `<Vendor>_key.EFI` key files that then contain all the keys that the
|
||||
individual components for their products are signed with. This file name needs
|
||||
to be registered at the time of shim review and should not be changed without
|
||||
going back to a shim review. A vendor should be able to store as many
|
||||
@ -354,14 +354,14 @@ them.
|
||||
|
||||
Adding a .sbat section containing the SBAT metadata structure to PE images.
|
||||
|
||||
| field | meaning |
|
||||
|---|---|
|
||||
| component_name | the name we're comparing
|
||||
| component_generation | the generation number for the comparison
|
||||
| vendor_name | human readable vendor name
|
||||
| vendor_package_name | human readable package name
|
||||
| vendor_version | human readable package version (maybe machine parseable too, not specified here)
|
||||
| vendor_url | url to look stuff up, contact, whatever.
|
||||
| field | meaning |
|
||||
|----------------------|----------------------------------------------------------------------------------|
|
||||
| component_name | the name we're comparing |
|
||||
| component_generation | the generation number for the comparison |
|
||||
| vendor_name | human readable vendor name |
|
||||
| vendor_package_name | human readable package name |
|
||||
| vendor_version | human readable package version (maybe machine parseable too, not specified here) |
|
||||
| vendor_url | url to look stuff up, contact, whatever. |
|
||||
|
||||
The format of this .sbat section is comma separated values, or more
|
||||
specifically ASCII encoded strings.
|
||||
@ -448,7 +448,7 @@ fixed. The following show the evolution over a sample set of events:
|
||||
|
||||
## Starting point
|
||||
|
||||
Before CVEs are encountered, an undesirable moudule was built into the a fedora
|
||||
Before CVEs are encountered, an undesirable module was built into Fedora's
|
||||
grub, so it's product-specific generation number has been bumped:
|
||||
|
||||
```
|
||||
|
108
SbatLevel_Variable.txt
Normal file
108
SbatLevel_Variable.txt
Normal file
@ -0,0 +1,108 @@
|
||||
In order to apply SBAT based revocations on systems that will never
|
||||
run shim, code running in boot services context needs to set the
|
||||
following variable:
|
||||
|
||||
Name: SbatLevel
|
||||
Attributes: (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
|
||||
Namespace Guid: 605dab50-e046-4300-abb6-3dd810dd8b23
|
||||
|
||||
Variable content:
|
||||
|
||||
Initialized, no revocations:
|
||||
|
||||
sbat,1,2021030218
|
||||
|
||||
To Revoke GRUB2 binaries impacted by
|
||||
|
||||
* CVE-2021-3695
|
||||
* CVE-2021-3696
|
||||
* CVE-2021-3697
|
||||
* CVE-2022-28733
|
||||
* CVE-2022-28734
|
||||
* CVE-2022-28735
|
||||
* CVE-2022-28736
|
||||
|
||||
sbat,1,2022052400
|
||||
grub,2
|
||||
|
||||
and shim binaries impacted by
|
||||
|
||||
* CVE-2022-28737
|
||||
|
||||
sbat,1,2022052400
|
||||
shim,2
|
||||
grub,2
|
||||
|
||||
Shim delivered both versions of these revocations with
|
||||
the same 2022052400 date stamp, once as an opt-in latest
|
||||
revocation with shim,2 and then as an automatic revocation without
|
||||
shim,2
|
||||
|
||||
|
||||
To revoke GRUB2 grub binaries impacted by
|
||||
|
||||
* CVE-2022-2601
|
||||
* CVE-2022-3775
|
||||
|
||||
sbat,1,2022111500
|
||||
shim,2
|
||||
grub,3
|
||||
|
||||
To revoke Debian's grub.3 which missed
|
||||
the patches:
|
||||
|
||||
sbat,1,2023012900
|
||||
shim,2
|
||||
grub,3
|
||||
grub.debian,4
|
||||
|
||||
|
||||
An additonal bug was fixed in shim that was not considered exploitable,
|
||||
can be revoked by setting:
|
||||
|
||||
sbat,1,2023012950
|
||||
shim,3
|
||||
grub,3
|
||||
grub.debian,4
|
||||
|
||||
shim did not deliver this payload at the time
|
||||
|
||||
|
||||
To Revoke GRUB2 binaries impacted by:
|
||||
|
||||
* CVE-2023-4692
|
||||
* CVE-2023-4693
|
||||
|
||||
These CVEs are in the ntfs module and vendors that do and do not
|
||||
ship this module as part of their signed binary are split.
|
||||
|
||||
sbat,1,2023091900
|
||||
shim,2
|
||||
grub,4
|
||||
|
||||
Since not everyone has shipped updated GRUB packages, shim did not
|
||||
deliver this revocation at the time.
|
||||
|
||||
To Revoke shim binaries impacted by:
|
||||
|
||||
* CVE-2023-40547
|
||||
* CVE-2023-40546
|
||||
* CVE-2023-40548
|
||||
* CVE-2023-40549
|
||||
* CVE-2023-40550
|
||||
* CVE-2023-40551
|
||||
|
||||
sbat,1,2024010900
|
||||
shim,4
|
||||
grub,3
|
||||
grub.debian,4
|
||||
|
||||
Since http boot shim CVE is considerably more serious than then GRUB
|
||||
ntfs CVEs shim is delivering the shim revocation without the updated
|
||||
GRUB revocation as a latest payload.
|
||||
|
||||
To revoke both the impacted shim and impacted GRUB binaries:
|
||||
|
||||
sbat,1,2024<date TBD>
|
||||
shim,4
|
||||
grub,4
|
1
cert.S
1
cert.S
@ -52,3 +52,4 @@ vendor_deauthorized:
|
||||
#endif
|
||||
.Lvendor_deauthorized_end:
|
||||
.Lcert_table_end:
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -1,2 +1,2 @@
|
||||
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
|
||||
shim,3,UEFI shim,shim,1,https://github.com/rhboot/shim
|
||||
shim,4,UEFI shim,shim,1,https://github.com/rhboot/shim
|
||||
|
|
3
errlog.c
3
errlog.c
@ -32,6 +32,9 @@ VLogError(const char *file, int line, const char *func, const CHAR16 *fmt,
|
||||
ms_va_list args2;
|
||||
CHAR16 **newerrs;
|
||||
|
||||
if (file == NULL || func == NULL || fmt == NULL)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
newerrs = ReallocatePool(errs, (nerrs + 1) * sizeof(*errs),
|
||||
(nerrs + 3) * sizeof(*errs));
|
||||
if (!newerrs)
|
||||
|
12
fallback.c
12
fallback.c
@ -1006,14 +1006,14 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
|
||||
EFI_HANDLE image_handle;
|
||||
|
||||
if (get_fallback_verbose()) {
|
||||
int fallback_verbose_wait = 500000; /* default to 0.5s */
|
||||
unsigned long fallback_verbose_wait = 500000; /* default to 0.5s */
|
||||
#ifdef FALLBACK_VERBOSE_WAIT
|
||||
fallback_verbose_wait = FALLBACK_VERBOSE_WAIT;
|
||||
#endif
|
||||
console_print(L"Verbose enabled, sleeping for %d mseconds... "
|
||||
L"Press the Pause key now to hold for longer.\n",
|
||||
fallback_verbose_wait);
|
||||
msleep(fallback_verbose_wait);
|
||||
usleep(fallback_verbose_wait);
|
||||
}
|
||||
|
||||
if (!first_new_option) {
|
||||
@ -1036,7 +1036,7 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
|
||||
}
|
||||
console_print(L"\n");
|
||||
|
||||
msleep(500000000);
|
||||
usleep(500000000);
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
@ -1051,7 +1051,7 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
|
||||
efi_status = BS->StartImage(image_handle, NULL, NULL);
|
||||
if (EFI_ERROR(efi_status)) {
|
||||
console_print(L"StartImage failed: %r\n", efi_status);
|
||||
msleep(500000000);
|
||||
usleep(500000000);
|
||||
}
|
||||
return efi_status;
|
||||
}
|
||||
@ -1211,14 +1211,14 @@ reset:
|
||||
console_print(L"Reset System\n");
|
||||
|
||||
if (get_fallback_verbose()) {
|
||||
int fallback_verbose_wait = 500000; /* default to 0.5s */
|
||||
unsigned long fallback_verbose_wait = 500000; /* default to 0.5s */
|
||||
#ifdef FALLBACK_VERBOSE_WAIT
|
||||
fallback_verbose_wait = FALLBACK_VERBOSE_WAIT;
|
||||
#endif
|
||||
console_print(L"Verbose enabled, sleeping for %d mseconds... "
|
||||
L"Press the Pause key now to hold for longer.\n",
|
||||
fallback_verbose_wait);
|
||||
msleep(fallback_verbose_wait);
|
||||
usleep(fallback_verbose_wait);
|
||||
}
|
||||
|
||||
RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
|
71
fuzz-csv.c
Normal file
71
fuzz-csv.c
Normal file
@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
/*
|
||||
* test-csv.c - test our csv parser
|
||||
*/
|
||||
|
||||
#ifndef SHIM_UNIT_TEST
|
||||
#define SHIM_UNIT_TEST
|
||||
#endif
|
||||
#include "shim.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
test_csv_simple_fuzz(char *random_bin, size_t random_bin_len)
|
||||
{
|
||||
list_t entry_list;
|
||||
size_t i;
|
||||
char *current, *end;
|
||||
list_t *pos = NULL;
|
||||
EFI_STATUS efi_status;
|
||||
|
||||
INIT_LIST_HEAD(&entry_list);
|
||||
|
||||
current = &random_bin[0];
|
||||
current = current + 1 - 1;
|
||||
end = current + random_bin_len - 1;
|
||||
*end = '\0';
|
||||
|
||||
efi_status = parse_csv_data(current, end, 7, &entry_list);
|
||||
if (efi_status != EFI_SUCCESS)
|
||||
return 0;
|
||||
if (list_size(&entry_list) <= 1)
|
||||
goto fail;
|
||||
|
||||
i = 0;
|
||||
list_for_each(pos, &entry_list) {
|
||||
struct csv_row *csv_row;
|
||||
|
||||
csv_row = list_entry(pos, struct csv_row, list);
|
||||
i++;
|
||||
}
|
||||
|
||||
free_csv_list(&entry_list);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
free_csv_list(&entry_list);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
int rc;
|
||||
uint8_t *data_copy;
|
||||
|
||||
if (size < 1)
|
||||
return 0;
|
||||
|
||||
data_copy = malloc(size);
|
||||
if (!data_copy)
|
||||
return -1;
|
||||
|
||||
memcpy(data_copy, data, size);
|
||||
rc = test_csv_simple_fuzz((char *)data_copy, size);
|
||||
free(data_copy);
|
||||
|
||||
return rc; // Values other than 0 and -1 are reserved for future use.
|
||||
}
|
||||
|
||||
// vim:fenc=utf-8:tw=75:noet
|
38
fuzz-pe-relocate.c
Normal file
38
fuzz-pe-relocate.c
Normal file
@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
/*
|
||||
* fuzz-pe-relocate.c - fuzz our PE relocation code.
|
||||
* Copyright Peter Jones <pjones@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef SHIM_UNIT_TEST
|
||||
#define SHIM_UNIT_TEST
|
||||
#endif
|
||||
#include "shim.h"
|
||||
|
||||
UINT8 mok_policy = 0;
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t *data_copy;
|
||||
EFI_STATUS status = 0;
|
||||
size_t n = 0;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT context = { 0, };
|
||||
|
||||
if (size < 1)
|
||||
return 0;
|
||||
|
||||
data_copy = malloc(size+1);
|
||||
if (!data_copy)
|
||||
return -1;
|
||||
|
||||
memcpy(data_copy, data, size);
|
||||
data_copy[size] = 0;
|
||||
|
||||
status = read_header(data_copy, size, &context);
|
||||
|
||||
free(data_copy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// vim:fenc=utf-8:tw=75:noet
|
46
fuzz-sbat.c
Normal file
46
fuzz-sbat.c
Normal file
@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
/*
|
||||
* fuzz-sbat-section.c - fuzz our .sbat parsing code
|
||||
* Copyright Peter Jones <pjones@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef SHIM_UNIT_TEST
|
||||
#define SHIM_UNIT_TEST
|
||||
#endif
|
||||
#include "shim.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
list_t sbat_var;
|
||||
|
||||
BOOLEAN
|
||||
secure_mode() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t *data_copy;
|
||||
EFI_STATUS status = 0;
|
||||
size_t n = 0;
|
||||
struct sbat_section_entry **entries = NULL;
|
||||
|
||||
if (size < 1)
|
||||
return 0;
|
||||
|
||||
data_copy = malloc(size+1);
|
||||
if (!data_copy)
|
||||
return -1;
|
||||
|
||||
memcpy(data_copy, data, size);
|
||||
data_copy[size] = 0;
|
||||
status = parse_sbat_section(data_copy, size, &n, &entries);
|
||||
cleanup_sbat_section_entries(n, entries);
|
||||
|
||||
free(data_copy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// vim:fenc=utf-8:tw=75:noet
|
@ -205,7 +205,7 @@ endif
|
||||
|
||||
ASFLAGS += $(ARCH3264)
|
||||
LDFLAGS += -nostdlib --warn-common --no-undefined --fatal-warnings \
|
||||
--build-id=sha1
|
||||
--build-id=sha1 --no-warn-rwx-segments
|
||||
|
||||
ifneq ($(ARCH),arm)
|
||||
export LIBGCC=$(shell $(CC) $(CFLAGS) $(ARCH3264) -print-libgcc-file-name)
|
||||
|
@ -41,3 +41,4 @@ _start:
|
||||
hello: .byte 'h',0,'e',0,'l',0,'l',0,'o',0,'\n',0,'\r',0,0,0
|
||||
|
||||
#endif
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -51,3 +51,4 @@ _start:
|
||||
.4byte .dummy1-.dummy0 // Page RVA
|
||||
.4byte 10 // Block Size (2*4+2)
|
||||
.2byte (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -191,3 +191,4 @@ _start:
|
||||
|
||||
.L_DYNAMIC:
|
||||
.word _DYNAMIC - .
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -75,3 +75,4 @@ _start:
|
||||
.4byte .dummy1-.dummy0 // Page RVA
|
||||
.4byte 10 // Block Size (2*4+2)
|
||||
.2byte (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -85,3 +85,4 @@ _start_plabel:
|
||||
data4 12 // Block Size (2*4+2*2)
|
||||
data2 (IMAGE_REL_BASED_DIR64<<12) + 0 // reloc for plabel's entry point
|
||||
data2 (IMAGE_REL_BASED_DIR64<<12) + 8 // reloc for plabel's global pointer
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -186,3 +186,4 @@ _pc:
|
||||
.end _start
|
||||
|
||||
.set pop
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -72,3 +72,4 @@ _start:
|
||||
.4byte .dummy1-.dummy0 // Page RVA
|
||||
.4byte 10 // Block Size (2*4+2)
|
||||
.2byte (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -225,3 +225,4 @@ apply_FPTR64:
|
||||
fptr_mem_base:
|
||||
.space MAX_FUNCTION_DESCRIPTORS*16
|
||||
fptr_mem_limit:
|
||||
.section .note.GNU-stack,"a"
|
||||
|
BIN
gnu-efi/ia32/gnuefi/crt0-efi-ia32.o
Normal file
BIN
gnu-efi/ia32/gnuefi/crt0-efi-ia32.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/gnuefi/libgnuefi.a
Normal file
BIN
gnu-efi/ia32/gnuefi/libgnuefi.a
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/gnuefi/reloc_ia32.o
Normal file
BIN
gnu-efi/ia32/gnuefi/reloc_ia32.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/boxdraw.o
Normal file
BIN
gnu-efi/ia32/lib/boxdraw.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/cmdline.o
Normal file
BIN
gnu-efi/ia32/lib/cmdline.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/console.o
Normal file
BIN
gnu-efi/ia32/lib/console.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/crc.o
Normal file
BIN
gnu-efi/ia32/lib/crc.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/data.o
Normal file
BIN
gnu-efi/ia32/lib/data.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/debug.o
Normal file
BIN
gnu-efi/ia32/lib/debug.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/dpath.o
Normal file
BIN
gnu-efi/ia32/lib/dpath.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/error.o
Normal file
BIN
gnu-efi/ia32/lib/error.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/event.o
Normal file
BIN
gnu-efi/ia32/lib/event.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/exit.o
Normal file
BIN
gnu-efi/ia32/lib/exit.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/guid.o
Normal file
BIN
gnu-efi/ia32/lib/guid.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/hand.o
Normal file
BIN
gnu-efi/ia32/lib/hand.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/hw.o
Normal file
BIN
gnu-efi/ia32/lib/hw.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/ia32/initplat.o
Normal file
BIN
gnu-efi/ia32/lib/ia32/initplat.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/ia32/math.o
Normal file
BIN
gnu-efi/ia32/lib/ia32/math.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/ia32/setjmp.o
Normal file
BIN
gnu-efi/ia32/lib/ia32/setjmp.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/init.o
Normal file
BIN
gnu-efi/ia32/lib/init.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/libefi.a
Normal file
BIN
gnu-efi/ia32/lib/libefi.a
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/lock.o
Normal file
BIN
gnu-efi/ia32/lib/lock.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/misc.o
Normal file
BIN
gnu-efi/ia32/lib/misc.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/pause.o
Normal file
BIN
gnu-efi/ia32/lib/pause.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/print.o
Normal file
BIN
gnu-efi/ia32/lib/print.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/runtime/efirtlib.o
Normal file
BIN
gnu-efi/ia32/lib/runtime/efirtlib.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/runtime/rtdata.o
Normal file
BIN
gnu-efi/ia32/lib/runtime/rtdata.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/runtime/rtlock.o
Normal file
BIN
gnu-efi/ia32/lib/runtime/rtlock.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/runtime/rtstr.o
Normal file
BIN
gnu-efi/ia32/lib/runtime/rtstr.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/runtime/vm.o
Normal file
BIN
gnu-efi/ia32/lib/runtime/vm.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/smbios.o
Normal file
BIN
gnu-efi/ia32/lib/smbios.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/sread.o
Normal file
BIN
gnu-efi/ia32/lib/sread.o
Normal file
Binary file not shown.
BIN
gnu-efi/ia32/lib/str.o
Normal file
BIN
gnu-efi/ia32/lib/str.o
Normal file
Binary file not shown.
@ -28,6 +28,6 @@ typedef struct {
|
||||
UINT64 D13;
|
||||
UINT64 D14;
|
||||
UINT64 D15;
|
||||
} ALIGN(JMPBUF_ALIGN) jmp_buf[1];
|
||||
} __attribute__((__aligned__(JMPBUF_ALIGN))) jmp_buf[1];
|
||||
|
||||
#endif /* GNU_EFI_AARCH64_SETJMP_H */
|
||||
|
@ -16,6 +16,6 @@ typedef struct {
|
||||
UINT32 R12;
|
||||
UINT32 R13;
|
||||
UINT32 R14;
|
||||
} ALIGN(JMPBUF_ALIGN) jmp_buf[1];
|
||||
} __attribute__((__aligned__(JMPBUF_ALIGN))) jmp_buf[1];
|
||||
|
||||
#endif /* GNU_EFI_ARM_SETJMP_H */
|
||||
|
@ -10,6 +10,6 @@ typedef struct {
|
||||
UINT32 Ebp;
|
||||
UINT32 Esp;
|
||||
UINT32 Eip;
|
||||
} ALIGN(JMPBUF_ALIGN) jmp_buf[1];
|
||||
} __attribute__((__aligned__(JMPBUF_ALIGN))) jmp_buf[1];
|
||||
|
||||
#endif /* GNU_EFI_IA32_SETJMP_H */
|
||||
|
@ -42,6 +42,6 @@ typedef struct {
|
||||
UINT64 Predicates;
|
||||
UINT64 LoopCount;
|
||||
UINT64 FPSR;
|
||||
} ALIGN(JMPBUF_ALIGN) jmp_buf[1];
|
||||
} __attribute__((__aligned__(JMPBUF_ALIGN))) jmp_buf[1];
|
||||
|
||||
#endif /* GNU_EFI_IA64_SETJMP_H */
|
||||
|
@ -29,6 +29,6 @@ typedef struct {
|
||||
UINT64 F30;
|
||||
UINT64 F31;
|
||||
#endif
|
||||
} ALIGN(JMPBUF_ALIGN) jmp_buf[1];
|
||||
} __attribute__((__aligned__(JMPBUF_ALIGN))) jmp_buf[1];
|
||||
|
||||
#endif /* GNU_EFI_MIPS64EL_SETJMP_H */
|
||||
|
@ -17,6 +17,6 @@ typedef struct {
|
||||
UINT64 Rip;
|
||||
UINT64 MxCsr;
|
||||
UINT8 XmmBuffer[160]; // XMM6 - XMM15
|
||||
} ALIGN(JMPBUF_ALIGN) jmp_buf[1];
|
||||
} __attribute__((__aligned__(JMPBUF_ALIGN))) jmp_buf[1];
|
||||
|
||||
#endif /* GNU_EFI_X86_64_SETJMP_H */
|
||||
|
@ -1 +1,2 @@
|
||||
/* This stub is a stub to make the build happy */
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -58,3 +58,4 @@ longjmp:
|
||||
mov w0, #1
|
||||
csel w0, w1, w0, ne
|
||||
br x30
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -153,3 +153,4 @@ label1:
|
||||
@ What to do about division by zero? For now, just return.
|
||||
ASM_PFX(__aeabi_idiv0):
|
||||
bx r14
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -1 +1,2 @@
|
||||
/* This stub is a stub to make the build happy */
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -59,3 +59,4 @@ L_Exit:
|
||||
|
||||
|
||||
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -39,3 +39,4 @@ ASM_PFX(__aeabi_llsl):
|
||||
lsl r1,r0,r3
|
||||
mov r0,#0
|
||||
bx lr
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -39,3 +39,4 @@ ASM_PFX(__aeabi_llsr):
|
||||
lsr r0,r1,r3
|
||||
mov r1,#0
|
||||
bx lr
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -31,3 +31,4 @@ ASM_PFX(__aeabi_lmul):
|
||||
mla r1, r2, r1, ip
|
||||
mla r1, r3, lr, r1
|
||||
ldmia sp!, {pc}
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -23,3 +23,4 @@ setjmp:
|
||||
.type longjmp, %function
|
||||
longjmp:
|
||||
ldmia r0, {r3-r12,r14}
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -265,3 +265,4 @@ ASM_PFX(__aeabi_ldiv0):
|
||||
bx r14
|
||||
|
||||
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -1 +1,2 @@
|
||||
/* This stub is a stub to make the build happy */
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -43,3 +43,4 @@ longjmp:
|
||||
movl (%edx), %ebx
|
||||
movl 4(%edx), %esi
|
||||
movl 8(%edx), %edi
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -159,3 +159,4 @@ StackedComeBackFromPALCall:
|
||||
|
||||
PROCEDURE_EXIT(MakeStackedPALCall)
|
||||
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -197,3 +197,4 @@ _skip_flushrs:
|
||||
invala
|
||||
mov ar.rsc = r16
|
||||
br.ret.sptk b0
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -1 +1,2 @@
|
||||
/* This stub is a stub to make the build happy */
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -90,3 +90,4 @@ longjmp:
|
||||
li $v0, 1
|
||||
movn $v0, $a1, $a1
|
||||
jr $ra
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -187,3 +187,4 @@ ENTRY(efi_call10)
|
||||
ret
|
||||
|
||||
#endif
|
||||
.section .note.GNU-stack,"a"
|
||||
|
@ -46,3 +46,4 @@ longjmp:
|
||||
cmp %rax,%rdx
|
||||
cmove %rcx,%rax
|
||||
jmp *0x38(%rdi)
|
||||
.section .note.GNU-stack,"a"
|
||||
|
16
httpboot.c
16
httpboot.c
@ -578,7 +578,13 @@ receive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINT64 *buf_size)
|
||||
}
|
||||
|
||||
if (*buf_size == 0) {
|
||||
perror(L"Failed to get Content-Lenght\n");
|
||||
perror(L"Failed to get Content-Length\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (*buf_size < rx_message.BodyLength) {
|
||||
efi_status = EFI_BAD_BUFFER_SIZE;
|
||||
perror(L"Invalid Content-Length\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -713,18 +719,20 @@ error:
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINT64 *buf_size)
|
||||
httpboot_fetch_buffer (EFI_HANDLE image, VOID **buffer, UINT64 *buf_size,
|
||||
CHAR8 *name)
|
||||
{
|
||||
EFI_STATUS efi_status;
|
||||
EFI_HANDLE nic;
|
||||
CHAR8 next_loader[sizeof DEFAULT_LOADER_CHAR];
|
||||
CHAR8 *next_loader;
|
||||
CHAR8 *next_uri = NULL;
|
||||
CHAR8 *hostname = NULL;
|
||||
|
||||
if (!uri)
|
||||
return EFI_NOT_READY;
|
||||
|
||||
translate_slashes(next_loader, DEFAULT_LOADER_CHAR);
|
||||
next_loader = (CHAR8 *)AllocatePool((strlen(name) + 1) * sizeof (CHAR8));
|
||||
translate_slashes(next_loader, name);
|
||||
|
||||
/* Create the URI for the next loader based on the original URI */
|
||||
efi_status = generate_next_uri(uri, next_loader, &next_uri);
|
||||
|
@ -40,11 +40,11 @@ static inline void wait_for_debug(void)
|
||||
{
|
||||
uint64_t a, b;
|
||||
int x;
|
||||
extern void msleep(unsigned long msecs);
|
||||
extern void usleep(unsigned long usecs);
|
||||
|
||||
a = read_counter();
|
||||
for (x = 0; x < 1000; x++) {
|
||||
msleep(1000);
|
||||
usleep(1000);
|
||||
b = read_counter();
|
||||
if (a != b)
|
||||
break;
|
||||
|
@ -198,5 +198,55 @@
|
||||
#error shim has no cache_invalidate() implementation for this compiler
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
#define GNUC_PREREQ(maj, min) \
|
||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
#else
|
||||
#define GNUC_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
|
||||
#define CLANG_PREREQ(maj, min) \
|
||||
((__clang_major__ > (maj)) || \
|
||||
(__clang_major__ == (maj) && __clang_minor__ >= (min)))
|
||||
#else
|
||||
#define CLANG_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8)
|
||||
#define checked_add(addend0, addend1, sum) \
|
||||
__builtin_add_overflow(addend0, addend1, sum)
|
||||
#define checked_sub(minuend, subtrahend, difference) \
|
||||
__builtin_sub_overflow(minuend, subtrahend, difference)
|
||||
#define checked_mul(factor0, factor1, product) \
|
||||
__builtin_mul_overflow(factor0, factor1, product)
|
||||
#else
|
||||
#define checked_add(a0, a1, s) \
|
||||
({ \
|
||||
(*s) = ((a0) + (a1)); \
|
||||
0; \
|
||||
})
|
||||
#define checked_sub(s0, s1, d) \
|
||||
({ \
|
||||
(*d) = ((s0) - (s1)); \
|
||||
0; \
|
||||
})
|
||||
#define checked_mul(f0, f1, p) \
|
||||
({ \
|
||||
(*p) = ((f0) * (f1)); \
|
||||
0; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#define checked_div(dividend, divisor, quotient) \
|
||||
({ \
|
||||
bool _ret = True; \
|
||||
if ((divisor) != 0) { \
|
||||
_ret = False; \
|
||||
(quotient) = (dividend) / (divisor); \
|
||||
} \
|
||||
_ret; \
|
||||
})
|
||||
|
||||
#endif /* !COMPILER_H_ */
|
||||
// vim:fenc=utf-8:tw=75:et
|
||||
|
@ -106,8 +106,8 @@ extern UINT32 verbose;
|
||||
dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__ - 1, __func__, \
|
||||
##__VA_ARGS__)
|
||||
#else
|
||||
#define dprint_(...)
|
||||
#define dprint(fmt, ...)
|
||||
#define dprint_(...) ({ ; })
|
||||
#define dprint(fmt, ...) ({ ; })
|
||||
#endif
|
||||
|
||||
extern EFI_STATUS EFIAPI vdprint_(const CHAR16 *fmt, const char *file, int line,
|
||||
@ -122,7 +122,9 @@ extern EFI_STATUS EFIAPI vdprint_(const CHAR16 *fmt, const char *file, int line,
|
||||
extern EFI_STATUS print_crypto_errors(EFI_STATUS rc, char *file, const char *func, int line);
|
||||
#define crypterr(rc) print_crypto_errors((rc), __FILE__, __func__, __LINE__)
|
||||
|
||||
extern VOID msleep(unsigned long msecs);
|
||||
#ifndef SHIM_UNIT_TEST
|
||||
extern VOID usleep(unsigned long usecs);
|
||||
#endif
|
||||
|
||||
/* This is used in various things to determine if we should print to the
|
||||
* console */
|
||||
|
@ -21,6 +21,7 @@ fanalyzer-build-all : COMPILER=gcc
|
||||
fanalyzer-build-all : CCACHE_DISABLE=1
|
||||
fanalyzer-build-all : FEATUREFLAGS+=-fanalyzer
|
||||
fanalyzer-build-all : WERRFLAGS=-Werror=analyzer-null-dereference
|
||||
fanalyzer-build-all : IGNORE_COMPILER_ERRORS=" || :"
|
||||
fanalyzer-build-all : all
|
||||
|
||||
fanalyzer-no-openssl : | fanalyzer-test
|
||||
|
97
include/fuzz.mk
Normal file
97
include/fuzz.mk
Normal file
@ -0,0 +1,97 @@
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
# fuzz.mk - makefile to fuzz local test programs
|
||||
#
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
include Make.defaults
|
||||
|
||||
CC = clang
|
||||
VALGRIND ?=
|
||||
DEBUG_PRINTS ?= 0
|
||||
OPTIMIZATIONS ?= -Og -ggdb
|
||||
FUZZ_ARGS ?=
|
||||
CFLAGS = $(OPTIMIZATIONS) -std=gnu11 \
|
||||
-isystem $(TOPDIR)/include/system \
|
||||
$(EFI_INCLUDES) \
|
||||
-Iinclude -iquote . \
|
||||
-isystem /usr/include \
|
||||
-isystem $(shell $(CC) $(ARCH_CFLAGS) -print-file-name=include) \
|
||||
$(ARCH_CFLAGS) \
|
||||
-fsanitize=fuzzer,address \
|
||||
-fshort-wchar \
|
||||
-fno-builtin \
|
||||
-rdynamic \
|
||||
-fno-inline \
|
||||
-fno-eliminate-unused-debug-types \
|
||||
-fno-eliminate-unused-debug-symbols \
|
||||
-gpubnames \
|
||||
-grecord-gcc-switches \
|
||||
$(if $(findstring clang,$(CC)),-Wno-unknown-warning-option) \
|
||||
$(DEFAULT_WARNFLAGS) \
|
||||
-Wsign-compare \
|
||||
-Wno-deprecated-declarations \
|
||||
$(if $(findstring gcc,$(CC)),-Wno-unused-but-set-variable) \
|
||||
-Wno-unused-but-set-variable \
|
||||
-Wno-unused-variable \
|
||||
-Wno-pointer-sign \
|
||||
$(DEFAULT_WERRFLAGS) \
|
||||
-Werror=nonnull \
|
||||
$(shell $(CC) -Werror=nonnull-compare -E -x c /dev/null >/dev/null 2>&1 && echo -Werror=nonnull-compare) \
|
||||
$(ARCH_DEFINES) \
|
||||
-DEFI_FUNCTION_WRAPPER \
|
||||
-DGNU_EFI_USE_MS_ABI -DPAGE_SIZE=4096 \
|
||||
-DSHIM_UNIT_TEST \
|
||||
-DSHIM_ENABLE_LIBFUZZER \
|
||||
"-DDEFAULT_DEBUG_PRINT_STATE=$(DEBUG_PRINTS)"
|
||||
|
||||
# On some systems (e.g. Arch Linux), limits.h is in the "include-fixed" instead
|
||||
# of the "include" directory
|
||||
CFLAGS += -isystem $(shell $(CC) $(ARCH_CFLAGS) -print-file-name=include-fixed)
|
||||
|
||||
# And on Debian also check the multi-arch include path
|
||||
CFLAGS += -isystem /usr/include/$(shell $(CC) $(ARCH_CFLAGS) -print-multiarch)
|
||||
|
||||
libefi-test.a :
|
||||
$(MAKE) -C gnu-efi \
|
||||
COMPILER="$(COMPILER)" \
|
||||
CC="$(CC)" \
|
||||
ARCH=$(ARCH_GNUEFI) \
|
||||
TOPDIR=$(TOPDIR)/gnu-efi \
|
||||
-f $(TOPDIR)/gnu-efi/Makefile \
|
||||
clean lib
|
||||
mv gnu-efi/$(ARCH)/lib/libefi.a $@
|
||||
$(MAKE) -C gnu-efi \
|
||||
COMPILER="$(COMPILER)" \
|
||||
ARCH=$(ARCH_GNUEFI) \
|
||||
TOPDIR=$(TOPDIR)/gnu-efi \
|
||||
-f $(TOPDIR)/gnu-efi/Makefile \
|
||||
clean
|
||||
|
||||
fuzz-sbat_FILES = csv.c lib/variables.c lib/guid.c sbat_var.S mock-variables.c
|
||||
fuzz-sbat :: CFLAGS+=-DHAVE_GET_VARIABLE -DHAVE_GET_VARIABLE_ATTR -DHAVE_SHIM_LOCK_GUID
|
||||
|
||||
fuzzers := $(patsubst %.c,%,$(wildcard fuzz-*.c))
|
||||
|
||||
$(fuzzers) :: fuzz-% : | libefi-test.a
|
||||
|
||||
$(fuzzers) :: fuzz-% : test.c fuzz-%.c $(fuzz-%_FILES)
|
||||
$(CC) $(CFLAGS) -o $@ $(sort $^ $(wildcard $*.c) $(fuzz-$*_FILES)) libefi-test.a -lefivar
|
||||
$(VALGRIND) ./$@ -max_len=4096 -jobs=24 $(FUZZ_ARGS)
|
||||
|
||||
fuzz : $(fuzzers)
|
||||
$(MAKE) -f include/fuzz.mk fuzz-clean
|
||||
|
||||
fuzz-clean :
|
||||
@rm -vf random.bin libefi-test.a
|
||||
@rm -vf vgcore.* fuzz*.log
|
||||
|
||||
clean : fuzz-clean
|
||||
|
||||
all : fuzz-clean fuzz
|
||||
|
||||
.PHONY: $(fuzzers) all fuzz clean
|
||||
.SECONDARY: random.bin
|
||||
|
||||
# vim:ft=make
|
@ -37,5 +37,6 @@ extern EFI_GUID SECURITY2_PROTOCOL_GUID;
|
||||
extern EFI_GUID EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID;
|
||||
extern EFI_GUID SHIM_LOCK_GUID;
|
||||
extern EFI_GUID MOK_VARIABLE_STORE;
|
||||
extern EFI_GUID SECUREBOOT_EFI_NAMESPACE_GUID;
|
||||
|
||||
#endif /* SHIM_GUID_H */
|
||||
|
@ -12,6 +12,6 @@
|
||||
|
||||
extern BOOLEAN find_httpboot(EFI_HANDLE device);
|
||||
extern EFI_STATUS httpboot_fetch_buffer(EFI_HANDLE image, VOID **buffer,
|
||||
UINT64 *buf_size);
|
||||
UINT64 *buf_size, CHAR8 *name);
|
||||
|
||||
#endif /* SHIM_HTTPBOOT_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
extern BOOLEAN findNetboot(EFI_HANDLE image_handle);
|
||||
|
||||
extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle);
|
||||
extern EFI_STATUS parseNetbootinfo(EFI_HANDLE image_handle, CHAR8 *name);
|
||||
|
||||
extern EFI_STATUS FetchNetbootimage(EFI_HANDLE image_handle, VOID **buffer, UINT64 *bufsiz);
|
||||
|
||||
|
14
include/pe.h
14
include/pe.h
@ -21,6 +21,20 @@ EFI_STATUS verify_image(void *data, unsigned int datasize,
|
||||
EFI_STATUS
|
||||
verify_sbat_section(char *SBATBase, size_t SBATSize);
|
||||
|
||||
EFI_STATUS
|
||||
get_section_vma (UINTN section_num,
|
||||
char *buffer, size_t bufsz UNUSED,
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT *context,
|
||||
char **basep, size_t *sizep,
|
||||
EFI_IMAGE_SECTION_HEADER **sectionp);
|
||||
|
||||
EFI_STATUS
|
||||
get_section_vma_by_name (char *name, size_t namesz,
|
||||
char *buffer, size_t bufsz,
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT *context,
|
||||
char **basep, size_t *sizep,
|
||||
EFI_IMAGE_SECTION_HEADER **sectionp);
|
||||
|
||||
EFI_STATUS
|
||||
handle_image (void *data, unsigned int datasize,
|
||||
EFI_LOADED_IMAGE *li,
|
||||
|
@ -29,6 +29,9 @@
|
||||
#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)))
|
||||
#define ALIGN_POINTER(Pointer, Alignment) ((VOID *) (ALIGN_VALUE ((UINTN)(Pointer), (Alignment))))
|
||||
|
||||
// Check if `val` is evenly aligned to the page size.
|
||||
#define IS_PAGE_ALIGNED(val) (!((val) & EFI_PAGE_MASK))
|
||||
|
||||
//
|
||||
// PE32+ Subsystem type for EFI images
|
||||
//
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user