uefi-capsule: Copy in an updated shim if provided

If a shim is in the fwupd libexec/efi directory, it's intended to
be paired with the fwupd binary.
This commit is contained in:
Mario Limonciello 2023-02-09 10:43:21 -06:00
parent a075b90ca5
commit 2cbe25e8c3
6 changed files with 27 additions and 16 deletions

View File

@ -278,13 +278,14 @@ fu_uefi_bootmgr_bootnext(FuDevice *device,
g_autofree guint8 *opt = NULL; g_autofree guint8 *opt = NULL;
g_autofree gchar *source_app = NULL; g_autofree gchar *source_app = NULL;
g_autofree gchar *target_app = NULL; g_autofree gchar *target_app = NULL;
g_autofree gchar *source_shim = NULL;
/* skip for self tests */ /* skip for self tests */
if (g_getenv("FWUPD_UEFI_TEST") != NULL) if (g_getenv("FWUPD_UEFI_TEST") != NULL)
return TRUE; return TRUE;
/* if secure boot was turned on this might need to be installed separately */ /* if secure boot was turned on this might need to be installed separately */
source_app = fu_uefi_get_built_app_path(error); source_app = fu_uefi_get_built_app_path("fwupd", error);
if (source_app == NULL) if (source_app == NULL)
return FALSE; return FALSE;
@ -292,19 +293,16 @@ fu_uefi_bootmgr_bootnext(FuDevice *device,
secure_boot = fu_efivar_secure_boot_enabled(NULL); secure_boot = fu_efivar_secure_boot_enabled(NULL);
if (secure_boot) { if (secure_boot) {
/* test to make sure shim is there if we need it */ /* test to make sure shim is there if we need it */
source_shim = fu_uefi_get_built_app_path("shim", error);
shim_app = fu_uefi_get_esp_app_path(device, esp_path, "shim", error); shim_app = fu_uefi_get_esp_app_path(device, esp_path, "shim", error);
if (shim_app == NULL) if (shim_app == NULL)
return FALSE; return FALSE;
/* try to fallback to use UEFI removable path if the shim path doesn't exist */ /* copy in an updated shim if we have one */
if (!g_file_test(shim_app, G_FILE_TEST_EXISTS)) { if (g_file_test(source_shim, G_FILE_TEST_EXISTS)) {
if (fu_device_has_private_flag( if (!fu_uefi_cmp_asset(source_shim, shim_app)) {
device, if (!fu_uefi_copy_asset(source_shim, shim_app, error))
FU_UEFI_DEVICE_FLAG_FALLBACK_TO_REMOVABLE_PATH)) {
g_free(shim_app);
shim_app =
fu_uefi_get_fallback_app_path(device, esp_path, "boot", error);
if (shim_app == NULL)
return FALSE; return FALSE;
} }
} }

View File

@ -111,7 +111,7 @@ fu_uefi_capsule_plugin_fwupd_efi_probe(FuUefiCapsulePlugin *self, GError **error
g_autofree gchar *fn = NULL; g_autofree gchar *fn = NULL;
/* find the app binary */ /* find the app binary */
fn = fu_uefi_get_built_app_path(error); fn = fu_uefi_get_built_app_path("fwupd", error);
if (fn == NULL) if (fn == NULL)
return FALSE; return FALSE;
self->fwupd_efi_file = g_file_new_for_path(fn); self->fwupd_efi_file = g_file_new_for_path(fn);

View File

@ -85,8 +85,21 @@ fu_uefi_get_esp_app_path(FuDevice *device, const gchar *esp_path, const gchar *c
return g_strdup_printf("%s/%s%s.efi", base, cmd, suffix); return g_strdup_printf("%s/%s%s.efi", base, cmd, suffix);
} }
/**
* fu_uefi_get_built_app_path:
* @basename: the prefix for the binary
* @error: (nullable): optional return location for an error
*
* Gets the path intended to be used for an EFI binary on the local system.
* The binary is matched against the correct architecture and if secure
* boot is enabled.
*
* Returns: The full path to the binary, or %NULL if not found
*
* Since: 1.8.1
**/
gchar * gchar *
fu_uefi_get_built_app_path(GError **error) fu_uefi_get_built_app_path(const gchar *binary, GError **error)
{ {
const gchar *suffix; const gchar *suffix;
g_autofree gchar *prefix = NULL; g_autofree gchar *prefix = NULL;
@ -100,7 +113,7 @@ fu_uefi_get_built_app_path(GError **error)
return NULL; return NULL;
prefix = fu_path_from_kind(FU_PATH_KIND_EFIAPPDIR); prefix = fu_path_from_kind(FU_PATH_KIND_EFIAPPDIR);
source_path = g_strdup_printf("%s/fwupd%s.efi", prefix, suffix); source_path = g_strdup_printf("%s/%s%s.efi", prefix, binary, suffix);
source_path_signed = g_strdup_printf("%s.signed", source_path); source_path_signed = g_strdup_printf("%s.signed", source_path);
source_path_exists = g_file_test(source_path, G_FILE_TEST_EXISTS); source_path_exists = g_file_test(source_path, G_FILE_TEST_EXISTS);

View File

@ -69,7 +69,7 @@ fu_uefi_get_fallback_app_path(FuDevice *device,
gchar * gchar *
fu_uefi_get_esp_app_path(FuDevice *device, const gchar *esp_path, const gchar *cmd, GError **error); fu_uefi_get_esp_app_path(FuDevice *device, const gchar *esp_path, const gchar *cmd, GError **error);
gchar * gchar *
fu_uefi_get_built_app_path(GError **error); fu_uefi_get_built_app_path(const gchar *binary, GError **error);
gboolean gboolean
fu_uefi_get_bitmap_size(const guint8 *buf, fu_uefi_get_bitmap_size(const guint8 *buf,
gsize bufsz, gsize bufsz,

View File

@ -504,7 +504,7 @@ fu_uefi_device_write_update_info(FuUefiDevice *self,
static gboolean static gboolean
fu_uefi_check_asset(FuDevice *device, GError **error) fu_uefi_check_asset(FuDevice *device, GError **error)
{ {
g_autofree gchar *source_app = fu_uefi_get_built_app_path(error); g_autofree gchar *source_app = fu_uefi_get_built_app_path("fwupd", error);
if (source_app == NULL) { if (source_app == NULL) {
if (fu_efivar_secure_boot_enabled(NULL)) if (fu_efivar_secure_boot_enabled(NULL))
g_prefix_error(error, "missing signed bootloader for secure boot: "); g_prefix_error(error, "missing signed bootloader for secure boot: ");

View File

@ -170,7 +170,7 @@ fu_uefi_grub_device_write_firmware(FuDevice *device,
return FALSE; return FALSE;
/* if secure boot was turned on this might need to be installed separately */ /* if secure boot was turned on this might need to be installed separately */
source_app = fu_uefi_get_built_app_path(error); source_app = fu_uefi_get_built_app_path("fwupd", error);
if (source_app == NULL) if (source_app == NULL)
return FALSE; return FALSE;