mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-17 17:49:54 +00:00
trivial: Limit alignment to 2GB to fix a fuzzing crash
This meant defining alignment values in FuFirmware. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=32131
This commit is contained in:
parent
f0e77fb2ab
commit
119d260bd2
@ -40,6 +40,7 @@
|
|||||||
#include "fwupd-error.h"
|
#include "fwupd-error.h"
|
||||||
|
|
||||||
#include "fu-common.h"
|
#include "fu-common.h"
|
||||||
|
#include "fu-firmware.h"
|
||||||
#include "fu-volume-private.h"
|
#include "fu-volume-private.h"
|
||||||
|
|
||||||
#define UDISKS_DBUS_SERVICE "org.freedesktop.UDisks2"
|
#define UDISKS_DBUS_SERVICE "org.freedesktop.UDisks2"
|
||||||
@ -3245,7 +3246,7 @@ fu_common_uri_get_scheme (const gchar *uri)
|
|||||||
/**
|
/**
|
||||||
* fu_common_align_up:
|
* fu_common_align_up:
|
||||||
* @value: value to align
|
* @value: value to align
|
||||||
* @alignment: align to this power of 2
|
* @alignment: align to this power of 2, where 0x1F is the maximum value of 2GB
|
||||||
*
|
*
|
||||||
* Align a value to a power of 2 boundary, where @alignment is the bit position
|
* Align a value to a power of 2 boundary, where @alignment is the bit position
|
||||||
* to align to. If @alignment is zero then @value is always returned unchanged.
|
* to align to. If @alignment is zero then @value is always returned unchanged.
|
||||||
@ -3261,6 +3262,8 @@ fu_common_align_up (gsize value, guint8 alignment)
|
|||||||
gsize value_new;
|
gsize value_new;
|
||||||
guint32 mask = 1 << alignment;
|
guint32 mask = 1 << alignment;
|
||||||
|
|
||||||
|
g_return_val_if_fail (alignment <= FU_FIRMWARE_ALIGNMENT_2G, G_MAXSIZE);
|
||||||
|
|
||||||
/* no alignment required */
|
/* no alignment required */
|
||||||
if ((value & (mask - 1)) == 0)
|
if ((value & (mask - 1)) == 0)
|
||||||
return value;
|
return value;
|
||||||
|
@ -816,8 +816,18 @@ fu_firmware_build (FuFirmware *self, XbNode *n, GError **error)
|
|||||||
if (tmpval != G_MAXUINT64)
|
if (tmpval != G_MAXUINT64)
|
||||||
fu_firmware_set_offset (self, tmpval);
|
fu_firmware_set_offset (self, tmpval);
|
||||||
tmpval = xb_node_query_text_as_uint (n, "alignment", NULL);
|
tmpval = xb_node_query_text_as_uint (n, "alignment", NULL);
|
||||||
if (tmpval != G_MAXUINT64)
|
if (tmpval != G_MAXUINT64) {
|
||||||
|
if (tmpval > FU_FIRMWARE_ALIGNMENT_2G) {
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_FOUND,
|
||||||
|
"0x%x invalid, maximum is 0x%x",
|
||||||
|
(guint) tmpval,
|
||||||
|
(guint) FU_FIRMWARE_ALIGNMENT_2G);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
fu_firmware_set_alignment (self, (guint8) tmpval);
|
fu_firmware_set_alignment (self, (guint8) tmpval);
|
||||||
|
}
|
||||||
tmp = xb_node_query_text (n, "filename", NULL);
|
tmp = xb_node_query_text (n, "filename", NULL);
|
||||||
if (tmp != NULL) {
|
if (tmp != NULL) {
|
||||||
g_autoptr(GBytes) blob = NULL;
|
g_autoptr(GBytes) blob = NULL;
|
||||||
|
@ -83,6 +83,40 @@ typedef guint64 FuFirmwareFlags;
|
|||||||
#define FU_FIRMWARE_ID_SIGNATURE "signature"
|
#define FU_FIRMWARE_ID_SIGNATURE "signature"
|
||||||
#define FU_FIRMWARE_ID_HEADER "header"
|
#define FU_FIRMWARE_ID_HEADER "header"
|
||||||
|
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_1 0x00
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_2 0x01
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_4 0x02
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_8 0x03
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_16 0x04
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_32 0x05
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_64 0x06
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_128 0x07
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_256 0x08
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_512 0x09
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_1K 0x0A
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_2K 0x0B
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_4K 0x0C
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_8K 0x0D
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_16K 0x0E
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_32K 0x0F
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_64K 0x10
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_128K 0x11
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_256K 0x12
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_512K 0x13
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_1M 0x14
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_2M 0x15
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_4M 0x16
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_8M 0x17
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_16M 0x18
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_32M 0x19
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_64M 0x1A
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_128M 0x1B
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_256M 0x1C
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_512M 0x1D
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_1G 0x1E
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_2G 0x1F
|
||||||
|
#define FU_FIRMWARE_ALIGNMENT_4G 0x20
|
||||||
|
|
||||||
const gchar *fu_firmware_flag_to_string (FuFirmwareFlags flag);
|
const gchar *fu_firmware_flag_to_string (FuFirmwareFlags flag);
|
||||||
FuFirmwareFlags fu_firmware_flag_from_string (const gchar *flag);
|
FuFirmwareFlags fu_firmware_flag_from_string (const gchar *flag);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ fu_bcm57xx_stage1_image_write (FuFirmware *firmware, GError **error)
|
|||||||
static void
|
static void
|
||||||
fu_bcm57xx_stage1_image_init (FuBcm57xxStage1Image *self)
|
fu_bcm57xx_stage1_image_init (FuBcm57xxStage1Image *self)
|
||||||
{
|
{
|
||||||
fu_firmware_set_alignment (FU_FIRMWARE (self), 2);
|
fu_firmware_set_alignment (FU_FIRMWARE (self), FU_FIRMWARE_ALIGNMENT_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -353,7 +353,7 @@ fu_efi_firmware_file_init (FuEfiFirmwareFile *self)
|
|||||||
FuEfiFirmwareFilePrivate *priv = GET_PRIVATE (self);
|
FuEfiFirmwareFilePrivate *priv = GET_PRIVATE (self);
|
||||||
priv->attrib = FU_EFI_FIRMWARE_FILE_ATTRIB_NONE;
|
priv->attrib = FU_EFI_FIRMWARE_FILE_ATTRIB_NONE;
|
||||||
priv->type = FU_EFI_FIRMWARE_FILE_TYPE_RAW;
|
priv->type = FU_EFI_FIRMWARE_FILE_TYPE_RAW;
|
||||||
fu_firmware_set_alignment (FU_FIRMWARE (self), 3);
|
fu_firmware_set_alignment (FU_FIRMWARE (self), FU_FIRMWARE_ALIGNMENT_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -93,7 +93,7 @@ fu_efi_firmware_filesystem_write (FuFirmware *firmware, GError **error)
|
|||||||
static void
|
static void
|
||||||
fu_efi_firmware_filesystem_init (FuEfiFirmwareFilesystem *self)
|
fu_efi_firmware_filesystem_init (FuEfiFirmwareFilesystem *self)
|
||||||
{
|
{
|
||||||
fu_firmware_set_alignment (FU_FIRMWARE (self), 3);
|
fu_firmware_set_alignment (FU_FIRMWARE (self), FU_FIRMWARE_ALIGNMENT_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -252,7 +252,7 @@ fu_efi_firmware_section_init (FuEfiFirmwareSection *self)
|
|||||||
{
|
{
|
||||||
FuEfiFirmwareSectionPrivate *priv = GET_PRIVATE (self);
|
FuEfiFirmwareSectionPrivate *priv = GET_PRIVATE (self);
|
||||||
priv->type = FU_EFI_FIRMWARE_SECTION_TYPE_RAW;
|
priv->type = FU_EFI_FIRMWARE_SECTION_TYPE_RAW;
|
||||||
// fu_firmware_set_alignment (FU_FIRMWARE (self), 3);
|
// fu_firmware_set_alignment (FU_FIRMWARE (self), FU_FIRMWARE_ALIGNMENT_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -77,6 +77,7 @@ fu_efi_firmware_volume_parse (FuFirmware *firmware,
|
|||||||
guint32 attrs = 0;
|
guint32 attrs = 0;
|
||||||
guint32 sig = 0;
|
guint32 sig = 0;
|
||||||
guint64 fv_length = 0;
|
guint64 fv_length = 0;
|
||||||
|
guint8 alignment;
|
||||||
guint8 revision = 0;
|
guint8 revision = 0;
|
||||||
const guint8 *buf = g_bytes_get_data (fw, &bufsz);
|
const guint8 *buf = g_bytes_get_data (fw, &bufsz);
|
||||||
g_autofree gchar *guid_str = NULL;
|
g_autofree gchar *guid_str = NULL;
|
||||||
@ -129,7 +130,17 @@ fu_efi_firmware_volume_parse (FuFirmware *firmware,
|
|||||||
g_prefix_error (error, "failed to read attrs: ");
|
g_prefix_error (error, "failed to read attrs: ");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
fu_firmware_set_alignment (firmware, (attrs & 0x00ff0000) >> 16);
|
alignment = (attrs & 0x00ff0000) >> 16;
|
||||||
|
if (alignment > FU_FIRMWARE_ALIGNMENT_2G) {
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_FOUND,
|
||||||
|
"0x%x invalid, maximum is 0x%x",
|
||||||
|
(guint) alignment,
|
||||||
|
(guint) FU_FIRMWARE_ALIGNMENT_2G);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fu_firmware_set_alignment (firmware, alignment);
|
||||||
priv->attrs = attrs & 0xffff;
|
priv->attrs = attrs & 0xffff;
|
||||||
if (!fu_common_read_uint16_safe (buf, bufsz,
|
if (!fu_common_read_uint16_safe (buf, bufsz,
|
||||||
offset + FU_EFI_FIRMWARE_VOLUME_OFFSET_HDR_LEN,
|
offset + FU_EFI_FIRMWARE_VOLUME_OFFSET_HDR_LEN,
|
||||||
|
@ -83,7 +83,7 @@ fu_ifd_bios_parse (FuFirmware *firmware,
|
|||||||
static void
|
static void
|
||||||
fu_ifd_bios_init (FuIfdBios *self)
|
fu_ifd_bios_init (FuIfdBios *self)
|
||||||
{
|
{
|
||||||
fu_firmware_set_alignment (FU_FIRMWARE (self), 12);
|
fu_firmware_set_alignment (FU_FIRMWARE (self), FU_FIRMWARE_ALIGNMENT_4K);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -104,7 +104,7 @@ fu_ifd_image_write (FuFirmware *firmware, GError **error)
|
|||||||
static void
|
static void
|
||||||
fu_ifd_image_init (FuIfdImage *self)
|
fu_ifd_image_init (FuIfdImage *self)
|
||||||
{
|
{
|
||||||
fu_firmware_set_alignment (FU_FIRMWARE (self), 12);
|
fu_firmware_set_alignment (FU_FIRMWARE (self), FU_FIRMWARE_ALIGNMENT_4K);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user