trivial: Add a fu_memread_uint24_safe() to make some code more correct

This commit is contained in:
Richard Hughes 2022-07-12 21:54:51 +01:00
parent a7e1307bfd
commit a06dedb253
4 changed files with 61 additions and 3 deletions

View File

@ -123,14 +123,13 @@ fu_efi_firmware_section_parse(FuFirmware *firmware,
const guint8 *buf = g_bytes_get_data(fw, &bufsz); const guint8 *buf = g_bytes_get_data(fw, &bufsz);
g_autoptr(GBytes) blob = NULL; g_autoptr(GBytes) blob = NULL;
if (!fu_memread_uint32_safe(buf, if (!fu_memread_uint24_safe(buf,
bufsz, /* uint24_t! */ bufsz,
FU_EFI_FIRMWARE_SECTION_OFFSET_SIZE, FU_EFI_FIRMWARE_SECTION_OFFSET_SIZE,
&size, &size,
G_LITTLE_ENDIAN, G_LITTLE_ENDIAN,
error)) error))
return FALSE; return FALSE;
size &= 0xFFFFFF;
if (size < FU_EFI_FIRMWARE_SECTION_SIZE) { if (size < FU_EFI_FIRMWARE_SECTION_SIZE) {
g_set_error(error, g_set_error(error,
FWUPD_ERROR, FWUPD_ERROR,

View File

@ -578,6 +578,52 @@ fu_memread_uint16_safe(const guint8 *buf,
return TRUE; return TRUE;
} }
/**
* fu_memread_uint24_safe:
* @buf: source buffer
* @bufsz: maximum size of @buf, typically `sizeof(buf)`
* @offset: offset in bytes into @buf to copy from
* @value: (out) (nullable): the parsed value
* @endian: an endian type, e.g. %G_LITTLE_ENDIAN
* @error: (nullable): optional return location for an error
*
* Read a value from a buffer using a specified endian 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.
*
* Returns: %TRUE if @value was set, %FALSE otherwise
*
* Since: 1.8.3
**/
gboolean
fu_memread_uint24_safe(const guint8 *buf,
gsize bufsz,
gsize offset,
guint32 *value,
FuEndianType endian,
GError **error)
{
guint8 dst[3] = {0x0};
g_return_val_if_fail(buf != NULL, FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
if (!fu_memcpy_safe(dst,
sizeof(dst),
0x0, /* dst */
buf,
bufsz,
offset, /* src */
sizeof(dst),
error))
return FALSE;
if (value != NULL)
*value = fu_memread_uint24(dst, endian);
return TRUE;
}
/** /**
* fu_memread_uint32_safe: * fu_memread_uint32_safe:
* @buf: source buffer * @buf: source buffer

View File

@ -42,6 +42,13 @@ fu_memread_uint16_safe(const guint8 *buf,
FuEndianType endian, FuEndianType endian,
GError **error) G_GNUC_WARN_UNUSED_RESULT; GError **error) G_GNUC_WARN_UNUSED_RESULT;
gboolean gboolean
fu_memread_uint24_safe(const guint8 *buf,
gsize bufsz,
gsize offset,
guint32 *value,
FuEndianType endian,
GError **error) G_GNUC_WARN_UNUSED_RESULT;
gboolean
fu_memread_uint32_safe(const guint8 *buf, fu_memread_uint32_safe(const guint8 *buf,
gsize bufsz, gsize bufsz,
gsize offset, gsize offset,

View File

@ -1059,3 +1059,9 @@ LIBFWUPDPLUGIN_1.8.2 {
fu_volume_new_esp_for_path; fu_volume_new_esp_for_path;
local: *; local: *;
} LIBFWUPDPLUGIN_1.8.1; } LIBFWUPDPLUGIN_1.8.1;
LIBFWUPDPLUGIN_1.8.3 {
global:
fu_memread_uint24_safe;
local: *;
} LIBFWUPDPLUGIN_1.8.2;