mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-20 08:24:06 +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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
* @buf: source buffer
|
||||
|
@ -191,6 +191,10 @@ GBytes *fu_common_bytes_new_offset (GBytes *bytes,
|
||||
GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
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,
|
||||
gsize dst_sz,
|
||||
gsize dst_offset,
|
||||
|
@ -748,6 +748,7 @@ LIBFWUPDPLUGIN_1.5.6 {
|
||||
fu_firmware_new_from_gtypes;
|
||||
fu_hwids_add_smbios_override;
|
||||
fu_hwids_get_keys;
|
||||
fu_memdup_safe;
|
||||
fu_plugin_get_devices;
|
||||
local: *;
|
||||
} 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));
|
||||
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 */
|
||||
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));
|
||||
gboolean ret;
|
||||
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);
|
||||
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 */
|
||||
chk0 = g_ptr_array_index (chunks, 0);
|
||||
chk0_data = g_memdup (fu_chunk_get_data (chk0),
|
||||
fu_chunk_get_data_sz (chk0));
|
||||
chk0_data = fu_memdup_safe (fu_chunk_get_data (chk0),
|
||||
fu_chunk_get_data_sz (chk0),
|
||||
error);
|
||||
if (chk0_data == NULL)
|
||||
return FALSE;
|
||||
chk0_data[0] = 0x00;
|
||||
if (!fu_hailuck_bl_device_write_block (self,
|
||||
chk0_data,
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <glib/gstdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fu-common.h"
|
||||
#include "fu-rom.h"
|
||||
|
||||
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 */
|
||||
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 */
|
||||
hdr->entry_point = ((guint32) buffer[0x05] << 16) +
|
||||
@ -582,7 +585,8 @@ fu_rom_load_data (FuRom *self,
|
||||
hdr->last_image = 0x80;
|
||||
hdr->rom_offset = hdr_sz + jump;
|
||||
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;
|
||||
g_ptr_array_add (self->hdrs, hdr);
|
||||
} else {
|
||||
|
@ -95,7 +95,13 @@ fu_rts54hub_device_write_flash (FuRts54HubDevice *self,
|
||||
{
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
|
||||
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,
|
||||
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
|
||||
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 */
|
||||
buf2 = g_memdup (buf, sz);
|
||||
buf2 = fu_memdup_safe (buf, sz, error);
|
||||
if (buf2 == NULL)
|
||||
return NULL;
|
||||
buf2[signature_offset] = 0x7f;
|
||||
return g_bytes_new_take (g_steal_pointer (&buf2), sz);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user