Age | Commit message (Collapse) | Author |
|
bump shim SBAT generation requirement to 2 for CVE-2022-28737
bump GRUB2 SBAT generation requirement to 2 for CVE-2021-3695
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
|
Coverity complains:
CID 373676 (#3 of 3): Unrecoverable parse warning (PARSE_ERROR)
1. arguments_provided_for_attribute: attribute "__malloc__" does not take arguments
This is, of course, just plain wrong. Even so, I'm tired of looking at
it, so this patch wraps the #define we use for that attribute in a check
to see if it's being built by Coverity.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
There are a couple of places where the code we've got right now just
uses integers to decode one of our MoK variables. That's bad.
This patch replaces those with symbolic names.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
scan-build invoked clang in a way that complains about our
SIGNATURE_XX() macro's sizes being used to assign to things that are
that size in post-process-pe.c.
This patch makes them cast the results to the appropriately sized type.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Support for updating SBAT revocations to latest or previous revocations.
Allow SBAT revocations to be reset to empty metadata only when UEFI
Secure Boot is disabled.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
This adds a new MoK variable, MokPolicy (&MokPolicyRT) that's intended
as a bitmask of machine owner policy choices, and the bit
MOK_POLICY_REQUIRE_NX. This bit specifies whether it is permissible to
load binaries which do not support NX mitigations, and it currently
defaults to allowing such binaries to be loaded.
The broader intention here is to migrate all of the MoK policy variables
that are really just on/off flags to this variable.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This adds support in our PE loader for NX support utilizing the
EFI_MEMORY_ATTRIBUTE protocol. Specifically, it changes the loader such
that:
- binaries without the EFI_IMAGE_DLLCHARACTERISTICS_NX_COMPAT flag set
in the Optional Header are rejected as EFI_UNSUPPORTED
- binaries with non-discardable sections that have both the
EFI_SCN_MEM_WRITE and EFI_SCN_MEM_EXECUTE flags set are rejected as
EFI_UNSUPPORTED
- if the EFI_MEMORY_ATTRIBUTE protocol is installed, then:
- sections without the EFI_SCN_MEM_READ flag set will be marked with
EFI_MEMORY_RP
- sections without the EFI_SCN_MEM_WRITE flag set will be marked with
EFI_MEMORY_RO
- sections without the EFI_SCN_MEM_EXECUTE flag set will be marked
with EFI_MEMORY_XP
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This patch adds some missing definitions for PE header flags. We don't
use all of them, but it's less confusing with the list matching the
spec, except where the spec is obviously wrong.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Heavily inspired by Matthew Garrett's patch "Allow additional certificates
to be loaded from a signed binary".
Add support for loading a binary, verifying its signature, and then
scanning it for embedded certificates. This is intended to make it
possible to decouple shim builds from vendor signatures. In order to
add new signatures to shim, an EFI Signature List should be generated
and then added to the .db section of a well-formed EFI binary. This
binary should then be signed with a key that shim already trusts (either
a built-in key, one present in the platform firmware or
one present in MOK) and placed in the same directory as shim with a
filename starting "shim_certificate" (eg, "shim_certificate_oracle").
Shim will read multiple files and incorporate the signatures from all of
them. Note that each section *must* be an EFI Signature List, not a raw
certificate.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
In the future we will want to examine binaries without wanting to
execute them. Create verify_image based off existing handle_image
code.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
Within previous versions of shim the MokListTrusted var did not
exist. The user had to opt in to using the feature.
Change the default behavior to an opt out model. Since old
shims will not have the BS MokListTrusted set, use inverse
logic that sets the MokListTrustedRT to 1 when the boot
service variable is missing.
Many Linux distros carry out of tree patches to trust the mok
keys by default. These out of tree patches can be dropped
when using a Linux kernel that supports MokListTrustedRT.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
On Debian(-derived) systems low-level system headers are under
/usr/include/<multi-arch path>, so look there too.
Otherwise we see stuff like:
gcc -O2 -fno-diagnostics-color -ggdb -std=gnu11 -isystem <foo>/shim.git/include/system -I<foo>/shim.git/gnu-efi/inc -I<foo>/shim.git/gnu-efi/inc/ia32 -I<foo>/shim.git/gnu-efi/inc/protocol -Iinclude -iquote . -isystem /usr/include -isystem /usr/lib/gcc/i686-linux-gnu/11/include -mno-mmx -mno-sse -mno-red-zone -nostdinc -maccumulate-outgoing-args -m32 -DMDE_CPU_IA32 -DPAGE_SIZE=4096 -fshort-wchar -fno-builtin -rdynamic -fno-inline -fno-eliminate-unused-debug-types -fno-eliminate-unused-debug-symbols -gpubnames -grecord-gcc-switches -Wall -Wextra -Wno-missing-field-initializers -Wsign-compare -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-unused-variable -Wno-pointer-sign -Werror -Werror=nonnull -Werror=nonnull-compare -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -DPAGE_SIZE=4096 -DSHIM_UNIT_TEST -DDEFAULT_DEBUG_PRINT_STATE=0 -isystem include-fixed -o test-csv csv.c test-csv.c test.c libefi-test.a -lefivar
In file included from /usr/include/bits/errno.h:26,
from /usr/include/errno.h:28,
from /usr/include/efivar/efivar.h:24,
from include/test.h:51,
from shim.h:68,
from csv.c:6:
/usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory
1 | #include <asm/errno.h>
| ^~~~~~~~~~~~~
compilation terminated.
In file included from /usr/include/bits/errno.h:26,
from /usr/include/errno.h:28,
from /usr/include/efivar/efivar.h:24,
from include/test.h:51,
from shim.h:68,
from test-csv.c:9:
/usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory
1 | #include <asm/errno.h>
| ^~~~~~~~~~~~~
compilation terminated.
In file included from /usr/include/bits/errno.h:26,
from /usr/include/errno.h:28,
from /usr/include/efivar/efivar.h:24,
from include/test.h:51,
from shim.h:68,
from test.c:7:
/usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory
1 | #include <asm/errno.h>
| ^~~~~~~~~~~~~
compilation terminated.
Signed-off-by: Steve McIntyre <steve@einval.com>
|
|
This implements SBAT verification via the shim_lock protocol
by moving verification inside the existing verify_buffer()
function that is shared by both shim_verify() and handle_image().
The .sbat section is optional for code verified via the shim_lock
protocol, unlike for code that is verified and executed directly
by shim. For executables that don't have a .sbat section,
verification is skipped when using the protocol.
A vendor can enforce SBAT verification for code verified via the
shim_lock protocol by revoking all pre-SBAT binaries via a dbx
update or by using vendor_dbx and then only signing binaries that
have a .sbat section from that point.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
|
- one missing free
- one minor deadcode issue
- two unchecked allocations
- one debug hexdump of a variable we just freed
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
cov-analysis-linux64-2020.09 is a lot more successful than the older
versions at building, but it still has some... issues. Among them, it
is of the belief that this:
void
foo(char *fmt, ...)
{
__builtin_va_list ap;
__builtin_ms_va_start(ap, fmt); /* <- here */
...
}
is an uninitialized use of "ap".
This patch adds defined(__COVERITY__) to the list of criteria for using
sysv va lists, which it has no such confusion about.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Several places in e.g. MokManager and our console library use
ST->ConOut->ClearScreen directly, without checking for the existence of
a console output device.
This patch adds function to our console library to do that correctly,
instead of using the bug-prone ad hoc implementation everywhere.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Copying the value of datasize_in to two further variables and then using
all three randomly in the code makes it hard to read.
datasize_in is never changed in generate_hash() so we can do with this
parameter alone. Rename it to datasize.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
|
|
On Arch Linux, the GCC version of "limits.h" is in the "include-fixed" instead
of the "include" directory. It needs to be included in the include directories
list, otherwise attempting to compile the test suite fails with the following
error:
In file included from /usr/include/efivar/efivar-dp.h:22,
from /usr/include/efivar/efivar.h:238,
from include/test.h:51,
from shim.h:68,
from csv.c:6:
/usr/include/limits.h:124:16: fatal error: limits.h: No such file or directory
124 | # include_next <limits.h>
| ^~~~~~~~~~
compilation terminated.
|
|
Currently valgrind shows a minor issue which is not introduced in this
patch series:
==2595397==
==2595397== HEAP SUMMARY:
==2595397== in use at exit: 16,368 bytes in 48 blocks
==2595397== total heap usage: 6,953 allocs, 6,905 frees, 9,146,749 bytes allocated
==2595397==
==2595397== 16,368 bytes in 48 blocks are definitely lost in loss record 1 of 1
==2595397== at 0x4845464: calloc (vg_replace_malloc.c:1117)
==2595397== by 0x4087F2: mock_efi_allocate_pool (test.c:72)
==2595397== by 0x4098DE: UnknownInlinedFun (misc.c:33)
==2595397== by 0x4098DE: AllocateZeroPool (misc.c:48)
==2595397== by 0x403D40: get_variable_attr (variables.c:301)
==2595397== by 0x4071C4: import_one_mok_state (mok.c:831)
==2595397== by 0x4072F4: import_mok_state (mok.c:908)
==2595397== by 0x407FA6: test_mok_mirror_0 (test-mok-mirror.c:205)
==2595397== by 0x4035B2: main (test-mok-mirror.c:378)
==2595397==
==2595397== LEAK SUMMARY:
==2595397== definitely lost: 16,368 bytes in 48 blocks
==2595397== indirectly lost: 0 bytes in 0 blocks
==2595397== possibly lost: 0 bytes in 0 blocks
==2595397== still reachable: 0 bytes in 0 blocks
==2595397== suppressed: 0 bytes in 0 blocks
==2595397==
This is because we're doing get_variable_attr() on the same variable
more than once and saving the value to our variables table. Each
additional time we do so leaks the previous one.
This patch solves the issue by not getting the variable again if it's
already set in the table, and adds a test case to check if we're doing
get_variable() of any variety on the same variable more than once.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Test that our mok mirroring doesn't ever try to delete any variable that
it has previously created, and that it properly mirrors at least
MokList, MokListX, and SbatLevel, at least when variables actually work.
These tests will fail (rather a lot) without 7f64fd6da9458b73c4.
Currently valgrind shows a memory leak in this code which is not
introduced in this patch series. Since all of our memory is freed on
Exit() or when kernel does ExitBootServices(), this doesn't have any
significant repercussions.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This adds a simple implementation of ST->ConfigurationTable,
ST->NumberOfTableEntries, and BS->InstallConfigurationTable to our test
harness.
Currently it is limited at 1024 entries, but that should be well more
than enough for any tests we've currently considered.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Some tests will need variables, and so we need a mock implementation of
the various calls relating to them.
This patch adds implementations for the EFI Runtime Services calls
GetVariable(), SetVariable(), GetNextVariableName(), and
QueryVariableInfo(). Additionally, it enforces tunable limits on
storage for variables, and (with only a little work) the limits can be
different for SetVariable() vs what is returned by QueryVariableInfo().
That is, it can lie to you like real systems do.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This adds more mock functions that just return various EFI error codes
in the EFIAPI ABI.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This adds a make target that builds the tests with gcov so we can
identify coverage gaps in the test suite.
It also makes a special test-lto invocation, so that a developer can run
these tests with the somewhat different optimization results LTO will
have.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
When writing new tests, if we get to the point where we have to use
libefivar for something, it's very common that I accidentally link it in
twice. When that happens, I typically spend an unfortunate amount of
time staring at FLTO's mangled names before I figure out what I've done
wrong.
This patch makes all the tests link against libefivar, thereby
avoiding the issue.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
None of this should ever actually get called when we're running any of
the unit tests we've got, but some older compilers (i.e. Centos 7's gcc)
fail to remove some of the intermediate functions, and that causes a
link error with the functions they call.
This patch makes the top level call go away as well, so that the
intermediates never have linkage to the underlying implementation
functions.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This lets us access the definitions for this structure, and the data
being used at runtime, from unit tests.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
5f08e671e4eb introduced a CompareGuid() call in the unit test harness,
but unfortunately it has a typo and thus only ever compares the first
pointer-sized word of the guid. With 4-GUIDs, this will usually produce
the correct results; with 1-GUIDs it often won't.
A second issue is that the memcmp() implementation of CompareGuid()
produces a different sort order than comparing field-by-field, and also
a different sort order than comparing the string representation. This
is often not a problem (edk2, for example, never compares anything
except equality of two GUIDs), but when writing test cases it is
extremely helpful to be able to look at a list that is sorted in an
intuitive order.
This patch introduces a guidcmp() function in the test suite, which
compares the binary data in the same order that comparing the two GUIDs'
string representations would.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This makes sure we clean up the builds that aren't for the EFI
environment after we build and run the unit tests.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
A couple of places snuck in where building with COMPILER=clang didn't
work right; this makes them work again.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
There is no need to check the parameters of strntoken() twice.
Fixes: c7bb10cf154a ("Tidy up our string primitives...")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
|
|
This adds tests for all the cases we've documented in the
set_second_stage() comments. Each test checks that all of second_stage,
loader_str, and loader_str_size are set correctly.
Note that this adds a dependency on libefivar to build device paths to
test against.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This moves set_second_stage() and some of the helper functions it uses
out of shim.c, so that it's easier to write test cases for.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Some tests have some complex flows, and it's useful to be able to see
the call path when there's a failure.
This patch adds a very simple traceback printer, along with changing the
test build arguments to include more debug information.
The result you get from this traceback printer just gives you a function
name and the index into its .txt content, so to use it for more than
"which function calls which", you'll need to use eu-addr2line with the
output.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This test helper was conspicuously missing, so this patch just adds it
at the obvious place.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
In some test cases, it may be useful to call libefi.a functions, such as
the device path parsing functions, which allocate pages via
BS->AllocatePool() or BS->AllocatePages.
This patch ads a simple mock implementation of those functions, as well
as the EFI_SYSTEM_TABLE, EFI_BOOT_SERVICES, and EFI_RUNTIME_SERVICES
variables *ST, *BS, and *RT (respectively), and initializes them before
the test cases run.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This allows us to use library functions from libefi.a in our test
programs.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
In some test cases, it's useful to be able to call some of the very
common stuff in gnu-efi's efilib.h (i.e. CompareGuid()), but including
that header itself is too big for me to tackle right now.
This patch adds a few more decls to test.h.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
pause() is a posix function, and having it named the same as this makes
it hard to include the asm.h header in some test cases.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
The load options handling is quite complicated and tries to accomodate
several scenarios, but there are currently multiple issues:
- If the supplied LoadOptions is an EFI_LOAD_OPTION structure,
second_stage gets initialized to the entire contents of the OptionalData
field and load_options is initialized to NULL, which means it isn't
possible to pass additional options to the second stage loader (and it
looks like the intention is for this to be supported).
- If the supplied LoadOptions contains 2 or more strings, the code seems
to assume that shim was executed from the UEFI shell and that the first
argument is the path of the shim executable, so it's ignored. But this
breaks the ability to pass additional options to the second stage loader
from BDS on firmware implementations that initialize LoadOptions to just
the OptionalData field of the EFI_LOAD_OPTION, which is what EDK2 seems
to do.
This is moot anyway because this case (strings == 2) doesn't actually seem
to work, as nothing sets loader_len and therefore second_stage is not set
to the custom loader path.
- If the supplied LoadOptions contains a single string that isn't shim's
path, nothing sets loader_len and therefore second_stage isn't set at the
end of set_second_stage.
- set_second_stage replaces L' ' characters with L'\0' - whilst this is
useful to NULL terminate the path for the second stage, it doesn't seem
quite right to do this for the remaining LoadOptions data. Grub's
chainloader command supplies additional arguments as a NULL-terminated
space-delimited string via LoadOptions. Making it NULL-delimited seems to
be incompatible with the kernel's commandline handling, which wouldn't
work for scenarios where you might want to direct-boot a kernel image
(wrapped in systemd's EFI stub) from shim.
- handle_image passes the original LoadOptions to the second stage if
load_options is NULL, which means that the second stage currently always
gets shim's load options.
I've made an attempt to try to fix things. After the initial
checks in set_second_stage, it now does this:
- Tries to parse LoadOptions as an EFI_LOAD_OPTION in order to extract
the OptionalData if it is.
- If it's not an EFI_LOAD_OPTION, check if the first string is the
current shim path and ignore it if it is (the UEFI shell case).
- Split LoadOptions in to a single NULL terminated string (used to
initialize second_stage) and the unmodified remaining data (used to
initialize load_options and load_options_size).
I've also modified handle_image to always set LoadOptions and
LoadOptionsSize. If shim is executed with no options, or is only
executed with a single option to override the second stage loader
path, the second stage is executed with LoadOptions = NULL and
LoadOptionsSize = 0 now.
I've tested this on EDK2 and I can load a custom loader with extra
options from both BDS and the UEFI shell:
FS0:\> shimx64.efi test.efi
LoadOptionsSize: 0
LoadOptions: (null)
FS0:\> shimx64.efi test.efi
LoadOptionsSize: 0
LoadOptions: (null)
FS0:\> shimx64.efi test.efi foo bar
LoadOptionsSize: 16
LoadOptions: foo bar
|
|
Because a few shim builds were signed that did not properly initialize
the SBAT variable, and in doing so deleted valid SBAT variables, we need
to use a different name.
This changes the name from "SBAT" to "SbatLevel".
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
|
This moves the check for the SBAT variable's attributes and contents
into its own function, so that test cases can be written against it.
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
|
|
|
|
The MOK variable mirroring makes use of variable_create_esl, which
can only create a well-formed EFI_SIGNATURE_LIST containing a single
signature. Fix fill_esl and variable_create_esl to support creating
a EFI_SIGNATURE_LIST with one or more supplied EFI_SIGNATURE_DATA
structures.
Introduce variable_create_esl_with_one_signature and
fill_esl_with_one_signature for code that does want to create a
EFI_SIGNATURE_LIST containing a single signature constructed from
a supplied signature data buffer and owner GUID.
|
|
Don't check SHIM_UNIT_TEST.
This fixes conflicting declarations for __builtin_ms_va_list on amd64:
In file included from shim.h:47,
from test.c:10:
../include/system/stdarg.h:30:27: error: conflicting types for '__builtin_ms_va_list'
typedef __builtin_va_list __builtin_ms_va_list;
^~~~~~~~~~~~~~~~~~~~
cc1: note: previous declaration of '__builtin_ms_va_list' was here
In file included from shim.h:47,
from test-csv.c:9:
../include/system/stdarg.h:30:27: error: conflicting types for '__builtin_ms_va_list'
typedef __builtin_va_list __builtin_ms_va_list;
^~~~~~~~~~~~~~~~~~~~
cc1: note: previous declaration of '__builtin_ms_va_list' was here
In file included from shim.h:47,
from csv.c:6:
../include/system/stdarg.h:30:27: error: conflicting types for '__builtin_ms_va_list'
typedef __builtin_va_list __builtin_ms_va_list;
^~~~~~~~~~~~~~~~~~~~
cc1: note: previous declaration of '__builtin_ms_va_list' was here
Signed-off-by: Steve McIntyre <93sam@debian.org>
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|