stub: restore compatibility for shim (< 16.0) -> UKI case
It is possible to boot directly a UKI from shim, and Fedora Cloud Base UKI
does exactly this.
This used to work fine until https://github.com/systemd/systemd/pull/37372
which broke compatibility when shim < 16.0 (no loader protocol override) is
used. Shim 15.8 is still in use in several distributions, and will be for
a long time.
Restore a part of the previous implementation, and if running with secure
boot enabled, and with shim but < 16.0, apply a security override.
Follow-up for cab9c7b5a4
Fixes https://github.com/systemd/systemd/issues/38104
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
0ccc31d964
commit
23d56ae890
+39
-1
@@ -22,6 +22,28 @@
|
||||
#define STUB_PAYLOAD_GUID \
|
||||
{ 0x55c5d1f8, 0x04cd, 0x46b5, { 0x8a, 0x20, 0xe5, 0x6c, 0xbb, 0x30, 0x52, 0xd0 } }
|
||||
|
||||
typedef struct {
|
||||
const void *addr;
|
||||
size_t len;
|
||||
const EFI_DEVICE_PATH *device_path;
|
||||
} ValidationContext;
|
||||
|
||||
static bool validate_payload(
|
||||
const void *ctx, const EFI_DEVICE_PATH *device_path, const void *file_buffer, size_t file_size) {
|
||||
|
||||
const ValidationContext *payload = ASSERT_PTR(ctx);
|
||||
|
||||
if (device_path != payload->device_path)
|
||||
return false;
|
||||
|
||||
/* Security arch (1) protocol does not provide a file buffer. Instead we are supposed to fetch the payload
|
||||
* ourselves, which is not needed as we already have everything in memory and the device paths match. */
|
||||
if (file_buffer && (file_buffer != payload->addr || file_size != payload->len))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static EFI_STATUS load_via_boot_services(
|
||||
EFI_HANDLE parent,
|
||||
EFI_LOADED_IMAGE_PROTOCOL* parent_loaded_image,
|
||||
@@ -43,6 +65,19 @@ static EFI_STATUS load_via_boot_services(
|
||||
|
||||
_cleanup_free_ EFI_DEVICE_PATH* file_path = device_path_replace_node(parent_loaded_image->FilePath, NULL, &device_node.Header);
|
||||
|
||||
/* When running with shim < v16 and booting a UKI directly from it, without a second stage loader,
|
||||
* the shim verify protocol needs to be called or it will raise a security violation when starting
|
||||
* the image (e.g.: Fedora Cloud Base UKI). TODO: drop once support for shim < v16 is not needed. */
|
||||
if (!shim_loader_available())
|
||||
install_security_override(
|
||||
validate_payload,
|
||||
&(ValidationContext) {
|
||||
.addr = kernel->iov_base,
|
||||
.len = kernel->iov_len,
|
||||
.device_path = file_path,
|
||||
});
|
||||
|
||||
|
||||
err = BS->LoadImage(/* BootPolicy= */false,
|
||||
parent,
|
||||
file_path,
|
||||
@@ -50,6 +85,9 @@ static EFI_STATUS load_via_boot_services(
|
||||
kernel->iov_len,
|
||||
&kernel_image);
|
||||
|
||||
if (!shim_loader_available())
|
||||
uninstall_security_override();
|
||||
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(EFI_LOAD_ERROR, "Error loading inner kernel with shim: %m");
|
||||
|
||||
@@ -131,7 +169,7 @@ EFI_STATUS linux_exec(
|
||||
*
|
||||
* See https://github.com/rhboot/shim/blob/main/README.md#shim-loader-protocol
|
||||
*/
|
||||
if (secure_boot_enabled() && shim_loader_available())
|
||||
if (secure_boot_enabled() && (shim_loader_available() || shim_loaded()))
|
||||
return load_via_boot_services(
|
||||
parent,
|
||||
parent_loaded_image,
|
||||
|
||||
Reference in New Issue
Block a user