mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-14 22:02:44 +00:00
Add fu_memdup_safe()
See https://mail.gnome.org/archives/desktop-devel-list/2021-February/msg00000.html for more details.
This commit is contained in:
parent
b5481f24d3
commit
9b11af985f
@ -2019,6 +2019,48 @@ fu_memcpy_safe (guint8 *dst, gsize dst_sz, gsize dst_offset,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_memdup_safe:
|
||||||
|
* @src: source buffer
|
||||||
|
* @n: number of bytes to copy from @src
|
||||||
|
* @error: A #GError or %NULL
|
||||||
|
*
|
||||||
|
* Duplicates some memory using memdup in a safe way.
|
||||||
|
*
|
||||||
|
* You don't need to use this function in "obviously correct" cases, nor should
|
||||||
|
* you use it when performance is a concern. Only us it when you're not sure if
|
||||||
|
* malicious data from a device or firmware could cause memory corruption.
|
||||||
|
*
|
||||||
|
* NOTE: This function intentionally limits allocation size to 1GB.
|
||||||
|
*
|
||||||
|
* Return value: (transfer full): block of allocated memory, or %NULL for an error.
|
||||||
|
*
|
||||||
|
* Since: 1.5.6
|
||||||
|
**/
|
||||||
|
guint8 *
|
||||||
|
fu_memdup_safe (const guint8 *src, gsize n, GError **error)
|
||||||
|
{
|
||||||
|
g_autofree guint8 *dst = NULL;
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
if (n > 0x40000000) {
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
"cannot allocate %uGB of memory",
|
||||||
|
(guint) (n / 0x40000000));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* linear block of memory */
|
||||||
|
dst = g_malloc (n);
|
||||||
|
if (!fu_memcpy_safe (dst, n, 0x0, /* dst */
|
||||||
|
src, n, 0x0, /* src */
|
||||||
|
n, error))
|
||||||
|
return NULL;
|
||||||
|
return g_steal_pointer (&dst);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fu_common_read_uint8_safe:
|
* fu_common_read_uint8_safe:
|
||||||
* @buf: source buffer
|
* @buf: source buffer
|
||||||
|
@ -191,6 +191,10 @@ GBytes *fu_common_bytes_new_offset (GBytes *bytes,
|
|||||||
GError **error)
|
GError **error)
|
||||||
G_GNUC_WARN_UNUSED_RESULT;
|
G_GNUC_WARN_UNUSED_RESULT;
|
||||||
gsize fu_common_strwidth (const gchar *text);
|
gsize fu_common_strwidth (const gchar *text);
|
||||||
|
guint8 *fu_memdup_safe (const guint8 *src,
|
||||||
|
gsize n,
|
||||||
|
GError **error)
|
||||||
|
G_GNUC_WARN_UNUSED_RESULT;
|
||||||
gboolean fu_memcpy_safe (guint8 *dst,
|
gboolean fu_memcpy_safe (guint8 *dst,
|
||||||
gsize dst_sz,
|
gsize dst_sz,
|
||||||
gsize dst_offset,
|
gsize dst_offset,
|
||||||
|
@ -748,6 +748,7 @@ LIBFWUPDPLUGIN_1.5.6 {
|
|||||||
fu_firmware_new_from_gtypes;
|
fu_firmware_new_from_gtypes;
|
||||||
fu_hwids_add_smbios_override;
|
fu_hwids_add_smbios_override;
|
||||||
fu_hwids_get_keys;
|
fu_hwids_get_keys;
|
||||||
|
fu_memdup_safe;
|
||||||
fu_plugin_get_devices;
|
fu_plugin_get_devices;
|
||||||
local: *;
|
local: *;
|
||||||
} LIBFWUPDPLUGIN_1.5.5;
|
} LIBFWUPDPLUGIN_1.5.5;
|
||||||
|
@ -194,7 +194,12 @@ fu_cros_ec_usb_device_do_xfer (FuCrosEcUsbDevice * self, const guint8 *outbuf,
|
|||||||
{
|
{
|
||||||
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
|
||||||
gsize actual = 0;
|
gsize actual = 0;
|
||||||
g_autofree guint8 *outbuf_tmp = g_memdup (outbuf, outlen);
|
g_autofree guint8 *outbuf_tmp = NULL;
|
||||||
|
|
||||||
|
/* make mutable */
|
||||||
|
outbuf_tmp = fu_memdup_safe (outbuf, outlen, error);
|
||||||
|
if (outbuf_tmp == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* send data out */
|
/* send data out */
|
||||||
if (outbuf != NULL && outlen > 0) {
|
if (outbuf != NULL && outlen > 0) {
|
||||||
|
@ -90,7 +90,12 @@ fu_fastboot_device_write (FuDevice *device, const guint8 *buf, gsize buflen, GEr
|
|||||||
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device));
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
gsize actual_len = 0;
|
gsize actual_len = 0;
|
||||||
g_autofree guint8 *buf2 = g_memdup (buf, (guint) buflen);
|
g_autofree guint8 *buf2 = NULL;
|
||||||
|
|
||||||
|
/* make mutable */
|
||||||
|
buf2 = fu_memdup_safe (buf, buflen, error);
|
||||||
|
if (buf2 == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
fu_fastboot_buffer_dump ("writing", buf, buflen);
|
fu_fastboot_buffer_dump ("writing", buf, buflen);
|
||||||
ret = g_usb_device_bulk_transfer (usb_device,
|
ret = g_usb_device_bulk_transfer (usb_device,
|
||||||
|
@ -219,8 +219,11 @@ fu_hailuck_bl_device_write_firmware (FuDevice *device,
|
|||||||
|
|
||||||
/* intentionally corrupt first chunk so that CRC fails */
|
/* intentionally corrupt first chunk so that CRC fails */
|
||||||
chk0 = g_ptr_array_index (chunks, 0);
|
chk0 = g_ptr_array_index (chunks, 0);
|
||||||
chk0_data = g_memdup (fu_chunk_get_data (chk0),
|
chk0_data = fu_memdup_safe (fu_chunk_get_data (chk0),
|
||||||
fu_chunk_get_data_sz (chk0));
|
fu_chunk_get_data_sz (chk0),
|
||||||
|
error);
|
||||||
|
if (chk0_data == NULL)
|
||||||
|
return FALSE;
|
||||||
chk0_data[0] = 0x00;
|
chk0_data[0] = 0x00;
|
||||||
if (!fu_hailuck_bl_device_write_block (self,
|
if (!fu_hailuck_bl_device_write_block (self,
|
||||||
chk0_data,
|
chk0_data,
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fu-common.h"
|
||||||
#include "fu-rom.h"
|
#include "fu-rom.h"
|
||||||
|
|
||||||
static void fu_rom_finalize (GObject *object);
|
static void fu_rom_finalize (GObject *object);
|
||||||
@ -423,7 +424,9 @@ fu_rom_pci_get_header (const guint8 *buffer, guint32 sz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy this locally to the header */
|
/* copy this locally to the header */
|
||||||
hdr->rom_data = g_memdup (buffer, hdr->rom_len);
|
hdr->rom_data = fu_memdup_safe (buffer, hdr->rom_len, NULL);
|
||||||
|
if (hdr->rom_data == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* parse out CPI */
|
/* parse out CPI */
|
||||||
hdr->entry_point = ((guint32) buffer[0x05] << 16) +
|
hdr->entry_point = ((guint32) buffer[0x05] << 16) +
|
||||||
@ -582,7 +585,8 @@ fu_rom_load_data (FuRom *self,
|
|||||||
hdr->last_image = 0x80;
|
hdr->last_image = 0x80;
|
||||||
hdr->rom_offset = hdr_sz + jump;
|
hdr->rom_offset = hdr_sz + jump;
|
||||||
hdr->rom_len = sz - hdr->rom_offset;
|
hdr->rom_len = sz - hdr->rom_offset;
|
||||||
hdr->rom_data = g_memdup (&buffer[hdr->rom_offset], hdr->rom_len);
|
hdr->rom_data = fu_memdup_safe (&buffer[hdr->rom_offset],
|
||||||
|
hdr->rom_len, NULL);
|
||||||
hdr->image_len = hdr->rom_len;
|
hdr->image_len = hdr->rom_len;
|
||||||
g_ptr_array_add (self->hdrs, hdr);
|
g_ptr_array_add (self->hdrs, hdr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -95,7 +95,13 @@ fu_rts54hub_device_write_flash (FuRts54HubDevice *self,
|
|||||||
{
|
{
|
||||||
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
|
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
|
||||||
gsize actual_len = 0;
|
gsize actual_len = 0;
|
||||||
g_autofree guint8 *datarw = g_memdup (data, datasz);
|
g_autofree guint8 *datarw = NULL;
|
||||||
|
|
||||||
|
/* make mutable */
|
||||||
|
datarw = fu_memdup_safe (data, datasz, error);
|
||||||
|
if (datarw == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!g_usb_device_control_transfer (usb_device,
|
if (!g_usb_device_control_transfer (usb_device,
|
||||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||||
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
G_USB_DEVICE_REQUEST_TYPE_VENDOR,
|
||||||
|
@ -412,7 +412,9 @@ fu_plugin_superio_fix_signature (FuSuperioDevice *self, GBytes *fw, GError **err
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fix signature to match SMT version */
|
/* fix signature to match SMT version */
|
||||||
buf2 = g_memdup (buf, sz);
|
buf2 = fu_memdup_safe (buf, sz, error);
|
||||||
|
if (buf2 == NULL)
|
||||||
|
return NULL;
|
||||||
buf2[signature_offset] = 0x7f;
|
buf2[signature_offset] = 0x7f;
|
||||||
return g_bytes_new_take (g_steal_pointer (&buf2), sz);
|
return g_bytes_new_take (g_steal_pointer (&buf2), sz);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user