uefi-capsule: Use GByteArray to make code more modern

This commit is contained in:
Richard Hughes 2022-04-07 12:38:15 +01:00
parent 92944f5074
commit 4bdd1d40e1

View File

@ -395,21 +395,21 @@ GBytes *
fu_uefi_device_fixup_firmware(FuUefiDevice *self, GBytes *fw, GError **error) fu_uefi_device_fixup_firmware(FuUefiDevice *self, GBytes *fw, GError **error)
{ {
FuUefiDevicePrivate *priv = GET_PRIVATE(self); FuUefiDevicePrivate *priv = GET_PRIVATE(self);
gsize fw_length; gsize bufsz;
const guint8 *data = g_bytes_get_data(fw, &fw_length); const guint8 *buf = g_bytes_get_data(fw, &bufsz);
g_autofree gchar *guid_new = NULL; g_autofree gchar *guid_new = NULL;
priv->missing_header = FALSE; priv->missing_header = FALSE;
/* GUID is the first 16 bytes */ /* GUID is the first 16 bytes */
if (fw_length < sizeof(fwupd_guid_t)) { if (bufsz < sizeof(fwupd_guid_t)) {
g_set_error_literal(error, g_set_error_literal(error,
FWUPD_ERROR, FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE, FWUPD_ERROR_INVALID_FILE,
"Invalid payload"); "Invalid payload");
return NULL; return NULL;
} }
guid_new = fwupd_guid_to_string((fwupd_guid_t *)data, FWUPD_GUID_FLAG_MIXED_ENDIAN); guid_new = fwupd_guid_to_string((fwupd_guid_t *)buf, FWUPD_GUID_FLAG_MIXED_ENDIAN);
/* ESRT header matches payload */ /* ESRT header matches payload */
if (g_strcmp0(fu_uefi_device_get_guid(self), guid_new) == 0) { if (g_strcmp0(fu_uefi_device_get_guid(self), guid_new) == 0) {
@ -419,17 +419,18 @@ fu_uefi_device_fixup_firmware(FuUefiDevice *self, GBytes *fw, GError **error)
FU_UEFI_DEVICE_FLAG_NO_CAPSULE_HEADER_FIXUP)) { FU_UEFI_DEVICE_FLAG_NO_CAPSULE_HEADER_FIXUP)) {
return g_bytes_ref(fw); return g_bytes_ref(fw);
} else { } else {
guint header_size = getpagesize(); guint hdrsize = getpagesize();
guint8 *new_data = g_malloc(fw_length + header_size);
guint8 *capsule = new_data + header_size;
fwupd_guid_t esrt_guid = {0x0}; fwupd_guid_t esrt_guid = {0x0};
efi_capsule_header_t *header = (efi_capsule_header_t *)new_data; efi_capsule_header_t header = {0x0};
g_autoptr(GByteArray) buf_hdr = g_byte_array_new();
g_warning("missing or invalid embedded capsule header"); g_warning("missing or invalid embedded capsule header");
priv->missing_header = TRUE; priv->missing_header = TRUE;
header->flags = priv->capsule_flags;
header->header_size = header_size; /* create a fake header with plausible contents */
header->capsule_image_size = fw_length + header_size; header.flags = priv->capsule_flags;
header.header_size = hdrsize;
header.capsule_image_size = bufsz + hdrsize;
if (!fwupd_guid_from_string(fu_uefi_device_get_guid(self), if (!fwupd_guid_from_string(fu_uefi_device_get_guid(self),
&esrt_guid, &esrt_guid,
FWUPD_GUID_FLAG_MIXED_ENDIAN, FWUPD_GUID_FLAG_MIXED_ENDIAN,
@ -437,10 +438,13 @@ fu_uefi_device_fixup_firmware(FuUefiDevice *self, GBytes *fw, GError **error)
g_prefix_error(error, "Invalid ESRT GUID: "); g_prefix_error(error, "Invalid ESRT GUID: ");
return NULL; return NULL;
} }
memcpy(&header->guid, &esrt_guid, sizeof(fwupd_guid_t)); memcpy(&header.guid, &esrt_guid, sizeof(fwupd_guid_t));
memcpy(capsule, data, fw_length);
return g_bytes_new_take(new_data, fw_length + header_size); /* prepend the header to the payload */
g_byte_array_append(buf_hdr, (const guint8 *)&header, sizeof(header));
fu_byte_array_set_size(buf_hdr, hdrsize);
g_byte_array_append(buf_hdr, buf, bufsz);
return g_byte_array_free_to_bytes(g_steal_pointer(&buf_hdr));
} }
} }
@ -452,9 +456,8 @@ fu_uefi_device_write_update_info(FuUefiDevice *self,
GError **error) GError **error)
{ {
FuUefiDevicePrivate *priv = GET_PRIVATE(self); FuUefiDevicePrivate *priv = GET_PRIVATE(self);
gsize datasz = 0;
gsize dp_bufsz = 0; gsize dp_bufsz = 0;
g_autofree guint8 *data = NULL; g_autoptr(GByteArray) buf = g_byte_array_new();
g_autofree guint8 *dp_buf = NULL; g_autofree guint8 *dp_buf = NULL;
efi_update_info_t info = { efi_update_info_t info = {
.update_info_version = 0x7, .update_info_version = 0x7,
@ -479,14 +482,12 @@ fu_uefi_device_write_update_info(FuUefiDevice *self,
/* save this header and body to the hardware */ /* save this header and body to the hardware */
if (!fwupd_guid_from_string(guid, &info.guid, FWUPD_GUID_FLAG_MIXED_ENDIAN, error)) if (!fwupd_guid_from_string(guid, &info.guid, FWUPD_GUID_FLAG_MIXED_ENDIAN, error))
return FALSE; return FALSE;
datasz = sizeof(info) + dp_bufsz; g_byte_array_append(buf, (const guint8 *)&info, sizeof(info));
data = g_malloc0(datasz); g_byte_array_append(buf, dp_buf, dp_bufsz);
memcpy(data, &info, sizeof(info));
memcpy(data + sizeof(info), dp_buf, dp_bufsz);
return fu_efivar_set_data(FU_EFIVAR_GUID_FWUPDATE, return fu_efivar_set_data(FU_EFIVAR_GUID_FWUPDATE,
varname, varname,
data, buf->data,
datasz, buf->len,
FU_EFIVAR_ATTR_NON_VOLATILE | FU_EFIVAR_ATTR_BOOTSERVICE_ACCESS | FU_EFIVAR_ATTR_NON_VOLATILE | FU_EFIVAR_ATTR_BOOTSERVICE_ACCESS |
FU_EFIVAR_ATTR_RUNTIME_ACCESS, FU_EFIVAR_ATTR_RUNTIME_ACCESS,
error); error);