mirror of
https://git.proxmox.com/git/fwupd
synced 2025-10-20 21:56:32 +00:00
pixart: Fuzz the firmware parser
This commit is contained in:
parent
7fb4397f25
commit
63a9665107
@ -303,6 +303,7 @@ def _build(bld: Builder) -> None:
|
|||||||
("cros-ec", "cros-ec", "cros-ec*"),
|
("cros-ec", "cros-ec", "cros-ec*"),
|
||||||
("ebitdo", "ebitdo", "ebitdo*"),
|
("ebitdo", "ebitdo", "ebitdo*"),
|
||||||
("hailuck", "hailuck-kbd", "ihex*"),
|
("hailuck", "hailuck-kbd", "ihex*"),
|
||||||
|
("pixart-rf", "pxi", "pixart*"),
|
||||||
("solokey", "solokey", "solokey*"),
|
("solokey", "solokey", "solokey*"),
|
||||||
("synaptics-prometheus", "synaprom", "synaprom*"),
|
("synaptics-prometheus", "synaprom", "synaprom*"),
|
||||||
("synaptics-rmi", "synaptics-rmi", "synaptics-rmi*"),
|
("synaptics-rmi", "synaptics-rmi", "synaptics-rmi*"),
|
||||||
|
@ -18,5 +18,5 @@ fu_plugin_init (FuPlugin *plugin)
|
|||||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||||
fu_plugin_add_udev_subsystem (plugin, "hidraw");
|
fu_plugin_add_udev_subsystem (plugin, "hidraw");
|
||||||
fu_plugin_set_device_gtype (plugin, FU_TYPE_PXI_DEVICE);
|
fu_plugin_set_device_gtype (plugin, FU_TYPE_PXI_DEVICE);
|
||||||
fu_plugin_add_firmware_gtype (plugin, "pixart", FU_TYPE_PXI_RF_FIRMWARE);
|
fu_plugin_add_firmware_gtype (plugin, "pixart", FU_TYPE_PXI_FIRMWARE);
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ fu_pxi_device_prepare_firmware (FuDevice *device,
|
|||||||
FwupdInstallFlags flags,
|
FwupdInstallFlags flags,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
g_autoptr(FuFirmware) firmware = fu_pxi_rf_firmware_new ();
|
g_autoptr(FuFirmware) firmware = fu_pxi_firmware_new ();
|
||||||
if (!fu_firmware_parse (firmware, fw, flags, error))
|
if (!fu_firmware_parse (firmware, fw, flags, error))
|
||||||
return NULL;
|
return NULL;
|
||||||
return g_steal_pointer (&firmware);
|
return g_steal_pointer (&firmware);
|
||||||
|
@ -7,25 +7,25 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "fu-common.h"
|
#include "fu-common.h"
|
||||||
|
#include "fu-common-version.h"
|
||||||
#include "fu-pxi-firmware.h"
|
#include "fu-pxi-firmware.h"
|
||||||
|
|
||||||
#define PIXART_RF_FW_HEADER_SIZE 32 /* bytes */
|
#define PIXART_RF_FW_HEADER_SIZE 32 /* bytes */
|
||||||
#define PIXART_RF_FW_HEADER_TAG_OFFSET 24
|
#define PIXART_RF_FW_HEADER_TAG_OFFSET 24
|
||||||
#define PIXART_RF_FW_HEADER_TAG_SIZE 8 /* bytes */
|
|
||||||
|
|
||||||
struct _FuPxiRfFirmware {
|
struct _FuPxiFirmware {
|
||||||
FuFirmware parent_instance;
|
FuFirmware parent_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (FuPxiRfFirmware, fu_pxi_rf_firmware, FU_TYPE_FIRMWARE)
|
G_DEFINE_TYPE (FuPxiFirmware, fu_pxi_firmware, FU_TYPE_FIRMWARE)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_pxi_rf_firmware_parse (FuFirmware *firmware,
|
fu_pxi_firmware_parse (FuFirmware *firmware,
|
||||||
GBytes *fw,
|
GBytes *fw,
|
||||||
guint64 addr_start,
|
guint64 addr_start,
|
||||||
guint64 addr_end,
|
guint64 addr_end,
|
||||||
FwupdInstallFlags flags,
|
FwupdInstallFlags flags,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
const guint8 *buf;
|
const guint8 *buf;
|
||||||
const guint8 tag[] = {
|
const guint8 tag[] = {
|
||||||
@ -33,6 +33,7 @@ fu_pxi_rf_firmware_parse (FuFirmware *firmware,
|
|||||||
};
|
};
|
||||||
gboolean header_ok = TRUE;
|
gboolean header_ok = TRUE;
|
||||||
gsize bufsz = 0;
|
gsize bufsz = 0;
|
||||||
|
guint32 version_raw = 0;
|
||||||
guint8 fw_header[PIXART_RF_FW_HEADER_SIZE];
|
guint8 fw_header[PIXART_RF_FW_HEADER_SIZE];
|
||||||
g_autoptr(FuFirmwareImage) img = fu_firmware_image_new (fw);
|
g_autoptr(FuFirmwareImage) img = fu_firmware_image_new (fw);
|
||||||
|
|
||||||
@ -90,20 +91,66 @@ fu_pxi_rf_firmware_parse (FuFirmware *firmware,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GBytes *
|
||||||
|
fu_pxi_firmware_write (FuFirmware *firmware, GError **error)
|
||||||
|
{
|
||||||
|
guint8 fw_header[PIXART_RF_FW_HEADER_SIZE] = { 0x0 };
|
||||||
|
guint64 version_raw = fu_firmware_get_version_raw (firmware);
|
||||||
|
g_autoptr(GByteArray) buf = NULL;
|
||||||
|
g_autoptr(GBytes) blob = NULL;
|
||||||
|
const guint8 tag[] = {
|
||||||
|
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* data first */
|
||||||
|
blob = fu_firmware_get_image_default_bytes (firmware, error);
|
||||||
|
if (blob == NULL)
|
||||||
|
return NULL;
|
||||||
|
buf = g_byte_array_sized_new (g_bytes_get_size (blob) + sizeof (fw_header));
|
||||||
|
g_byte_array_append (buf,
|
||||||
|
g_bytes_get_data (blob, NULL),
|
||||||
|
g_bytes_get_size (blob));
|
||||||
|
|
||||||
|
/* footer */
|
||||||
|
if (!fu_memcpy_safe (fw_header, sizeof (fw_header),
|
||||||
|
PIXART_RF_FW_HEADER_TAG_OFFSET, /* dst */
|
||||||
|
tag, sizeof(tag), 0x0, /* src */
|
||||||
|
sizeof(tag), error))
|
||||||
|
return NULL;
|
||||||
|
fw_header[0] = ((version_raw >> 16) & 0xff) + '0';
|
||||||
|
fw_header[1] = '.';
|
||||||
|
fw_header[2] = ((version_raw >> 8) & 0xff) + '0';
|
||||||
|
fw_header[3] = '.';
|
||||||
|
fw_header[4] = ((version_raw >> 0) & 0xff) + '0';
|
||||||
|
if (!g_ascii_isdigit (fw_header[0]) ||
|
||||||
|
!g_ascii_isdigit (fw_header[2]) ||
|
||||||
|
!g_ascii_isdigit (fw_header[4])) {
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
"cannot write invalid version number 0x%x",
|
||||||
|
(guint) version_raw);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
g_byte_array_append (buf, fw_header, sizeof(fw_header));
|
||||||
|
return g_byte_array_free_to_bytes (g_steal_pointer (&buf));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_pxi_rf_firmware_init (FuPxiRfFirmware *self)
|
fu_pxi_firmware_init (FuPxiFirmware *self)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_pxi_rf_firmware_class_init (FuPxiRfFirmwareClass *klass)
|
fu_pxi_firmware_class_init (FuPxiFirmwareClass *klass)
|
||||||
{
|
{
|
||||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||||
klass_firmware->parse = fu_pxi_rf_firmware_parse;
|
klass_firmware->parse = fu_pxi_firmware_parse;
|
||||||
|
klass_firmware->write = fu_pxi_firmware_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
FuFirmware *
|
FuFirmware *
|
||||||
fu_pxi_rf_firmware_new (void)
|
fu_pxi_firmware_new (void)
|
||||||
{
|
{
|
||||||
return FU_FIRMWARE (g_object_new (FU_TYPE_PXI_RF_FIRMWARE, NULL));
|
return FU_FIRMWARE (g_object_new (FU_TYPE_PXI_FIRMWARE, NULL));
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "fu-firmware.h"
|
#include "fu-firmware.h"
|
||||||
|
|
||||||
#define FU_TYPE_PXI_RF_FIRMWARE (fu_pxi_rf_firmware_get_type ())
|
#define FU_TYPE_PXI_FIRMWARE (fu_pxi_firmware_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (FuPxiRfFirmware, fu_pxi_rf_firmware, FU, PXI_RF_FIRMWARE, FuFirmware)
|
G_DECLARE_FINAL_TYPE (FuPxiFirmware, fu_pxi_firmware, FU, PXI_FIRMWARE, FuFirmware)
|
||||||
|
|
||||||
FuFirmware *fu_pxi_rf_firmware_new (void);
|
FuFirmware *fu_pxi_firmware_new (void);
|
||||||
|
@ -9,7 +9,7 @@ shared_module('fu_plugin_pixart_rf',
|
|||||||
sources : [
|
sources : [
|
||||||
'fu-plugin-pixart-rf.c',
|
'fu-plugin-pixart-rf.c',
|
||||||
'fu-pxi-device.c',
|
'fu-pxi-device.c',
|
||||||
'fu-pxi-firmware.c',
|
'fu-pxi-firmware.c', # fuzzing
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
root_incdir,
|
root_incdir,
|
||||||
|
BIN
src/fuzzing/firmware/pixart.bin
Normal file
BIN
src/fuzzing/firmware/pixart.bin
Normal file
Binary file not shown.
6
src/fuzzing/pixart.builder.xml
Normal file
6
src/fuzzing/pixart.builder.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<firmware gtype="FuPxiFirmware">
|
||||||
|
<version_raw>0x00010203</version_raw>
|
||||||
|
<image>
|
||||||
|
<data>aGVsbG8gd29ybGQ=</data> <!-- base64 -->
|
||||||
|
</image>
|
||||||
|
</firmware>
|
Loading…
Reference in New Issue
Block a user