Skip to content

Commit

Permalink
Optionally allow to keep shim protocol installed
Browse files Browse the repository at this point in the history
If the SHIM_RETAIN_PROTOCOL 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:

systemd/systemd#27358

Signed-off-by: Luca Boccassi <bluca@debian.org>
  • Loading branch information
bluca committed Apr 25, 2023
1 parent f23883c commit 8af9a3d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
19 changes: 18 additions & 1 deletion replacements.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,25 @@ replacement_start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 *
unhook_system_services();

if (image_handle == last_loaded_image) {
UINT8 *data = NULL;
UINTN dataSize = 0;
UINT32 attrs = 0;

loader_is_participating = 1;
uninstall_shim_protocols();

/* If a boot component asks us, keep our protocol around - it will be used to
* validate further PE payloads (e.g.: by the UKI stub, before the kernel is booted).
* But also check that the variable was set by a boot component, to ensure that
* nobody at runtime can attempt to change shim's behaviour. */
efi_status = get_variable_attr(SHIM_RETAIN_PROTOCOL_VAR_NAME, &data, &dataSize,
SHIM_LOCK_GUID, &attrs);
if (EFI_ERROR(efi_status) ||
(attrs & EFI_VARIABLE_NON_VOLATILE) ||
!(attrs & EFI_VARIABLE_BOOTSERVICE_ACCESS)) {
uninstall_shim_protocols();
} else {
FreePool(data);
}
}
efi_status = BS->StartImage(image_handle, exit_data_size, exit_data);
if (EFI_ERROR(efi_status)) {
Expand Down
6 changes: 6 additions & 0 deletions shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,12 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
#endif
}

/*
* This variable is supposed to be set by second stages, so ensure it is
* not set when we are starting up.
*/
(void) del_variable(SHIM_RETAIN_PROTOCOL_VAR_NAME, SHIM_LOCK_GUID);

efi_status = shim_init();
if (EFI_ERROR(efi_status)) {
msg = SHIM_INIT;
Expand Down
2 changes: 2 additions & 0 deletions shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ verify_buffer (char *data, int datasize,
#define DEBUG_VAR_NAME L"SHIM_DEBUG"
#endif

#define SHIM_RETAIN_PROTOCOL_VAR_NAME L"SHIM_RETAIN_PROTOCOL"

char *translate_slashes(char *out, const char *str);

#endif /* SHIM_H_ */

0 comments on commit 8af9a3d

Please sign in to comment.