Age | Commit message (Collapse) | Author |
|
Depending on ~something~ to do with the firmware that's currently really
unclear (to me anyway), on some firmwares making the mok variable config
table over a certain size - somewhere around 0x70000 or so bytes -
causes kernel to fail to map it correctly:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 0 at mm/early_ioremap.c:139 __early_ioremap+0xef/0x220
Modules linked in:
CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.12.15-200.fc41.x86_64 #1
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20250221-6.copr8698600 02/21/2025
RIP: 0010:__early_ioremap+0xef/0x220
Code: e5 00 f0 ff ff 48 81 e5 00 f0 ff ff 4c 89 6c 24 08 41 81 e4 ff 0f 00 00 4c 29 ed 48 89 e8 48 c1 e8 0c 41 89 c7 83 f8 40 76 04 <0f> 0b eb 82 45 6b ee c0 41 81 c5 ff 05 00 00 45 85 ff 74 36 83 3d
RSP: 0000:ffffffff96803dd8 EFLAGS: 00010002 ORIG_RAX: 0000000000000000
RAX: 0000000000000041 RBX: 0000000000000001 RCX: ffffffff97768250
RDX: 8000000000000163 RSI: 0000000000000001 RDI: 000000007c4c3000
RBP: 0000000000041000 R08: ffffffffff201630 R09: 0000000000000030
R10: 000000007c4c3000 R11: ffffffff96803e20 R12: 0000000000000000
R13: 000000007c4c3000 R14: 0000000000000001 R15: 0000000000000041
FS: 0000000000000000(0000) GS:ffffffff97291000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff9f1d8000040e CR3: 00000000653a4000 CR4: 00000000000000f0
Call Trace:
<TASK>
? __early_ioremap+0xef/0x220
? __warn.cold+0x93/0xfa
? __early_ioremap+0xef/0x220
? report_bug+0xff/0x140
? early_fixup_exception+0x5d/0xb0
? early_idt_handler_common+0x2f/0x3a
? __early_ioremap+0xef/0x220
? efi_mokvar_table_init+0xce/0x1d0
? setup_arch+0x864/0xc10
? start_kernel+0x6b/0xa10
? x86_64_start_reservations+0x24/0x30
? x86_64_start_kernel+0xed/0xf0
? common_startup_64+0x13e/0x141
</TASK>
---[ end trace 0000000000000000 ]---
mokvar: Failed to map EFI MOKvar config table pa=0x7c4c3000, size=265187.
Unfortunately this makes the *entire* mok variable store unmappable, and
we get nothing in /sys/firmware/efi/mok-variables/ at all.
For now, I've disabled saving the logs even though it's really
convenient to have, until we can collaborate on a better approach that
avoids this pitfall.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
hughsie asked me to also make it observable at runtime whether the shim
binary that was used to boot was set as NX_COMPAT or not.
This adds that into the HSIStatus data as "shim-has-nx-compat-set".
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
When we're parsing the PE header of shim itself from the Loaded Image
object, the signatures aren't present, but the Certificate Table entry
in the Data Directory has not been cleared, so it'll fail verification.
We know when we're doing that, so this patch makes that test optional.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
hughsie asked me if I can make shim tell userland what kinds of accesses
are allowed to the heap, stack, and allocations on the running platform,
so that these could be reported up through fwupd's Host Security ID
program (see https://fwupd.github.io/libfwupdplugin/hsi.html ).
This adds a new config-only (i.e. not a UEFI variable) variable
generated during boot, "/sys/firmware/efi/mok-variables/HSIStatus",
which tells us those properties as well as if the EFI Memory Attribute
Protocol is present.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This changes our debug and error logging to save the entire logs into
mok-variables as "shim-dbg.txt" and "shim-log.txt".
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Since we can't read the directory, we can try to load
shim_certificate_[0..9].efi explicitly and give up after
the first one that fails to load.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
While a revocations.efi binary can contain either SBAT revocations,
SkuSi revocations, or both, it is desirable to package them separately
so that higher level tools such as fwupd can decide which ones to put
in place at a given moment. This changes revocations.efi to
revocations_sbat.efi and revocations_sku.efi
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
Bugfix: In the netboot case revocations.efi files were read, but
processed as shim_certificate.efi files which is simply wrong.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
Reading files during a netboot comes with the caveat that
fetching files from a network does not support anything
like listing a directory. In the past this has meant that
we do not try to open optional files during a netboot.
However at least the revocation.efi file is now tested
during a netboot, which will print an error when it is not
found. Since that error is spurious we should allow for
those errors to be suppressed.
This is also desirable since we will likely go looking for
additional files in the near future.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
This adds an implementation of Exit() and UnloadImage(), removes the
whole "loader_is_participating" mechanism and its supporting code, and
removes DISABLE_EBS_PROTECTION.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
This moves some things around to help with loader protocol changes:
- Move replacements.c to loader-proto.c
- likewise with replacements.h
- move the SHIM_IMAGE_LOADER decl to loader-proto.h
- move the LoadImage / StartImage interface setup to an init function
- move shim_load_image() / shim_start_image() to loader-proto.c
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Define a new protocol for loading and starting images, encapsulating
shim's PE loading facilities and verification/authentication against the
same set of certificates that shim_lock::verify() authenticates against.
This removes the need for loaders like GRUB to implement their own PE
loader in order to be able to invoke loaded images as PE applications,
rather than implementing a bespoke OS dependent handover protocol (e.g.,
invoke Linux via its EFI stub)
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
|
|
Add the ability for shim to load an optional configuration file. This
new file is called "options.csv". The configuration file is completely
optional. If used, it is located in the same directory as the booted
shim. The "options.csv" file currently allows a single entry. Other
options could be added to it in the future. The first and only entry in
the file is the name of the secondary boot loader shim will load. The
"options.csv" file is in Unicode LE format.
This allows a signed shim to directly load a UKI without the need to
rename it to grub. Shim's transitive trust is maintained. If the
alternative 2nd stage can not be verified, it will not boot.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
For multiple reasons, it may be useful for different keys to be used to
sign different parts of the boot chain (e.g. a different key for GRUB
and the Linux kernel). Allow this by loading concatenated
EFI_SIGNATURE_LISTs from shim_certificate.efi rather than only the
first.
At the same time, be a bit more robust by checking for allocation
failures and overflows due to invalid data in the binary.
Use the smaller of VirtualSize and SizeOfRawData since the latter is
rounded up to the section alignment and therefore may contain
non-certificate data.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
|
|
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
|
|
Only certain errors trigger fall back to the default loader name. This
change allows fall back when encountering `EFI_TFTP_ERROR` and
`EFI_HTTP_ERROR`.
This fixes the issue reported in
https://github.com/rhboot/shim/issues/649 that prevents boot on some
models of PC.
Signed-off-by: Nathan O'Meara <Nathan.OMeara@tanium.com>
|
|
This just turns off the clang-tidy warning about our SBAT_VAR_NAME
string compositing in the error message list in efi_main(), as it's the
only warning in the whole file and it's bugging me.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
We need to use is_removable_media_path(), and potentially other helpers,
from Mok as well as shim.
This moves it to a file just for Device Path utility functions to make
that simpler.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Without the patch:
-----------------------------------------------------------------------
Failed to open \EFI\BOOT\mmx64.efi - Not Found
Failed to load image 貘給: Not Found
-----------------------------------------------------------------------
With the patch:
-----------------------------------------------------------------------
Failed to open \EFI\BOOT\mmx64.efi - Not Found
Failed to load image \EFI\BOOT\mmx64.efi: Not Found
-----------------------------------------------------------------------
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
|
|
The interface shouldn't be replaced at the shim_fini
stage When the vendor certificate doesn't exist.
Signed-off-by: jinlun <869793317@qq.com>
|
|
Signed-off-by: Chris Bainbridge <chris.bainbridge@gmail.com>
|
|
The code actually uses EFI_SECURE_BOOT_DB_GUID which is defined in
include/guid.h, drop the unused EFI_IMAGE_SECURITY_DATABASE_GUID define
from shim.c
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
|
In the ea0f9df "Allow SbatLevel data from external binary" patch
the code that tries to load any certificate file that starts with
shim_certificate was changed to only accept shim_certificate.efi
which defeats the entire point of reading through the directory.
This change reverts that.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
Network booting tends to expose things like a tfpt server
as a filesystem that doesn't implement directory listing
This will blindly try to ingest a revocations.efi file in
those cases, even if that may result in some console noise
when the file does not exist.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
The netboot path up until now hardcodes DEFAULT_LOADER as
the only possible filename to load. This is pretty limiting
and needs to be fixed.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
When the term previous was introduced for revocations to be
automatically applied there was a hope that everytime a new
revocation was built into shim, the previous revocation could
be applied automatically. Further experience has shown the
real world to be more complex than that. The automatic payload
will realistically contain a set of revocations governed by
both the cadence at which a distro's customer base updates
as well as the severity of the issue being revoked.
This is not a functional change.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
Attempting to call loadimage on revocations.efi when it isn't present
should results in error messages being printed to the console on at
least some firmware:
Failed to open \EFI\distro\revocations.efi - Not Found
Failed to load image ...: Not Found
Of course this is going to be the normal case on nearly all systems, at
least to begin with. Since we are about to loop through the directory
entries anyway, we can just make two passes, first looking for
revocations.efi and then looking for shim_certificate.efi. This will
still ensure that any revocations in revocations.efi are picked up
before shim_certificate.efi is loaded without resulting in any noise on
the console.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
Several of our CVE fixes apparently were not well tested on 32-bit, and
needed some (uintptr_t) casts sprinkled about to build with
-Werror=pointer-to-int-cast.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Inline PE section names (i.e. when not using the string table) are 8
byte arrays. They often look like ASCII strings, but they are not ASCII
strings.
This patch changes load_revocations_file() to always check that the full
array matches the section name in question.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Before applying an updated SbatLevel shim should re-run
introspection and never apply a revocation level that would
prevent the currently running shim from booting. The proper
way forward is to update shim first.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
This adds support for applying SkuSiPolicy UEFI BS variables. These
varaibles are needed for non-dbx based Windows revocations and are
described here:
https://support.microsoft.com/en-us/topic/kb5027455-guidance-for-blocking-vulnerable-windows-boot-managers-522bb851-0a61-44ad-aa94-ad11119c5e91
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
Ingest SBAT Levels from revocations binary thereby allowing level
requirements to be updated independently from shipping a new shim.
Do not automatically apply any revocations from a stock shim at
this point.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
In verify_sbat_section(), we do some math on data that comes from the
binary being verified - in this case, we add 1 to the size of the
".sbat" section as reported in the section header, which is then used as
the input to the size of an allocation. The original value is then used
for a size in a memcpy(), which means there's an out-of-bounds write in
the overflow case.
Due to the type of the variable being size_t, but the type in the
section header being uint32_t, this is only plausibly accomplished on
32-bit systems.
This patch makes the arithmetic use a checked add operation to avoid
overflow. Additionally, it adds a check in verify_buffer_sbat() to
guarantee that the data is within the binary.
It's not currently known if this is actually exploitable on such
systems; the memory layout on a particular machine may further mitigate
this scenario.
Resolves: CVE-2023-40548
Reported-by: gkirkpatrick@google.com
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
In the validation logic in verify_buffer_authenticode(), there is yet
another case where we need to guarantee an object is in the binary but
we're only validating the pointer to it. In this case, we're validating
that the actual signature data is in the binary, but unfortunately we
failed to validate that the header describing it is, so a malformed
binary can cause us to take an out-of-bounds read (probably but not
necessarily on the same page) past the end of the buffer.
This patch adds a bounds check to verify that the signature is
actually within the bounds.
It seems unlikely this can be used for more than a denial of service,
and if you can get shim to try to verify a malformed binary, you've
effectively already accomplished a DoS.
Resolves: CVE-2023-40549
Reported-by: gkirkpatrick@google.com
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
In verify_buffer_sbat(), we have a goal-seeking loop to find the .sbat
section header. Unfortunately, while the actual contents of the section
are checked for being inside the binary, no such check exists for the
contents of the section table entry.
As a result, a carefully constructed binary will cause an out-of-bounds
read checking if the section name is ".sbat\0\0\0" or not.
This patch adds a check that each section table entry is within the
bounds of the binary.
It's not currently known if this is actually exploitable beyond creating
a denial of service, and an attacker who is in a position to use it for
a denial of service attack must already be able to do so.
Resolves: CVE-2023-40550
Reported-by: gkirkpatrick@google.com
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Verifying the validity of a files signature can protect from
an attacker creating a file that exploits a potential issue
in the sbat validation. If the signature is not checked first,
an attacker can just create a file with a valid .sbat section
and can still attack the signature validation.
Signed-off-by: Jan Setje-Eilers <Jan.SetjeEilers@oracle.com>
|
|
The function msleep uses gBS->Stall which waits for a specified number
of microseconds.
Reference: https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/5_uefi_services/51_services_that_uefi_drivers_commonly_use/517_stall
This reference even mentions an example sleeping for 10 microseconds: // Wait 10 uS. Notice the letter 'u'.
Therefore it's a good idea to call the function 'usleep' rather than
'msleep', so no one confuses it with milliseconds, and to change the
argument name to match as well.
Signed-off-by: Kamil Aronowski <kamil.aronowski@yahoo.com>
|
|
Following the discovery of more problematic firmwares and drivers
affected by the issue f23883ccf78f1f605a272f9e5700f47e5494a71d is
designed to address (e.g. https://github.com/rhboot/shim/issues/558),
this patch further improves the code so that, instead of simply bailing
out, we progressively increase the buffer sizes, until either success
or a maximum size limit is reached.
In most cases, this workaround should be enough to ensure completion
of the directory read and thus provide full shim functionality (while
still warning the user about the non-compliance of their environment).
Signed-off-by: Pete Batard <pete@akeo.ie>
|
|
These calls did not check the return value. If they had, it would have
shown that the calls were failing due to passing `NULL` for the
`realloc` function pointer. That causes an early return, so the calls
weren't actually doing anything.
The `malloc`/`realloc`/`free` functions defined in
Cryptlib/SysCall/BaseMemAllocation.c are what actually get used, so just
drop the explicit call to `CRYPTO_set_mem_functions`.
Signed-off-by: Nicholas Bishop <nicholasbishop@google.com>
|
|
If the ShimRetainProtocol variable is set, avoid uninstalling our
protocol.
For example, this allows sd-stub in a UKI to use the shim protocol to
validate PE binaries, even if it is executed by a second stage, before
the kernel is loaded.
Ensure that the variable is volatile and for BootServices access.
Also delete it on startup, so that we can be sure it was really set by
a second stage.
Example use case in sd-boot/sd-stub:
https://github.com/systemd/systemd/pull/27358
Signed-off-by: Luca Boccassi <bluca@debian.org>
|
|
On DELL R350 booting DVD through RFS with BIOS 1.4.2 in Secure Boot,
firmware returns EFI_BUFFER_TOO_SMALL but with new buffersize set to 0,
which causes the load_certs() code to loop forever:
while (1) {
efi_status = dir->Read(dir, &buffersize, buffer);
if (efi_status == EFI_BUFFER_TOO_SMALL) {
...
continue;
}
...
}
This commit prevents such infinite loop.
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
|
|
Use the EFI RT memory function CopyMem instead of memcpy in load_cert_file.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
0214cd9cef5a fixes a NULL pointer dereference problem, it introduces two
new problems. First it incorrectly assumes li.FilePath is a string.
Second, it puts EFI_LOADED_IMAGE li on the stack. It has been found
that not all archectures can handle this being on the stack.
The shim_li variable will be setup properly from the read_image
call. Use the global shim_li variable instead when calling
verify_image.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
When calling back into shim from grub, the MokListRT may contain additional
entries not available in the original MokList, an example being the certs
included via user_cert. Use the MokListRT instead when calling check_db_cert
and check_db_hash.
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
Coverity noticed that the refactoring of handle_image() wildly
misunderstood how we deal with file paths.
This reworks it to not have a bunch of NULL dereferences.
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
scan-build says info->FileName returned from a successful call to
dir->Read() can be NULL. I don't think that would be a compliant
implementation, but anything's possible.
This patch checks it for NULL-ness before the StrCaseCmp().
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
scan-build noticed that there's a path where we'll pass some data from
the read_image() to e.g. the string functions, but it might be an
unassigned pointer on one of the code paths. I don't think you can
actually hit it without returning from an error first, but best to
initialize these anyway.
This patch initializes data to NULL and datasize to 0.
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>
|
|
Separate out image reading from image launch in order to be able to load
an image without executing it.
Signed-off-by: Matthew Garrett <mgarrett@aurora.tech>
Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
|
|
This makes SHIM_VERBOSE / SHIM_DEVEL_VERBOSE work the same way as
SHIM_DEBUG / SHIM_DEVEL_DEBUG when shim is built with ENABLE_SHIM_DEVEL
set.
Signed-off-by: Peter Jones <pjones@redhat.com>
|