mirror of
https://git.proxmox.com/git/fwupd
synced 2025-06-28 19:26:53 +00:00
elantp: Add support for writing the firmware image
This allows for fuzzing.
This commit is contained in:
parent
9b304fdfbd
commit
ae3ad67710
@ -303,6 +303,7 @@ def _build(bld: Builder) -> None:
|
||||
("ccgx", "ccgx-dmc", "ccgx-dmc*.bin"),
|
||||
("cros-ec", "cros-ec", "cros-ec*"),
|
||||
("ebitdo", "ebitdo", "ebitdo*"),
|
||||
("elantp", "elantp", "elantp*"),
|
||||
("hailuck", "hailuck-kbd", "ihex*"),
|
||||
("pixart-rf", "pxi", "pixart*"),
|
||||
("solokey", "solokey", "solokey*"),
|
||||
|
@ -20,7 +20,7 @@ struct _FuElantpFirmware {
|
||||
G_DEFINE_TYPE (FuElantpFirmware, fu_elantp_firmware, FU_TYPE_FIRMWARE)
|
||||
|
||||
/* firmware block update */
|
||||
#define ETP_IAP_START_ADDR 0x0083
|
||||
#define ETP_IAP_START_ADDR_WRDS 0x008
|
||||
|
||||
guint16
|
||||
fu_elantp_firmware_get_module_id (FuElantpFirmware *self)
|
||||
@ -60,15 +60,31 @@ fu_elantp_firmware_parse (FuFirmware *firmware,
|
||||
g_autoptr(FuFirmwareImage) img = fu_firmware_image_new (fw);
|
||||
|
||||
/* presumably in words */
|
||||
if (!fu_common_read_uint16_safe (buf, bufsz, ETP_IAP_START_ADDR * 2,
|
||||
if (!fu_common_read_uint16_safe (buf, bufsz, ETP_IAP_START_ADDR_WRDS * 2,
|
||||
&iap_addr_wrds, G_LITTLE_ENDIAN, error))
|
||||
return FALSE;
|
||||
if (iap_addr_wrds < ETP_IAP_START_ADDR_WRDS || iap_addr_wrds > 0x7FFF) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"IAP address invalid: 0x%x",
|
||||
iap_addr_wrds);
|
||||
return FALSE;
|
||||
}
|
||||
self->iap_addr = iap_addr_wrds * 2;
|
||||
|
||||
/* read module ID */
|
||||
if (!fu_common_read_uint16_safe (buf, bufsz, self->iap_addr,
|
||||
&module_id_wrds, G_LITTLE_ENDIAN, error))
|
||||
return FALSE;
|
||||
if (module_id_wrds > 0x7FFF) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"module ID address invalid: 0x%x",
|
||||
module_id_wrds);
|
||||
return FALSE;
|
||||
}
|
||||
if (!fu_common_read_uint16_safe (buf, bufsz, module_id_wrds * 2,
|
||||
&self->module_id, G_LITTLE_ENDIAN, error))
|
||||
return FALSE;
|
||||
@ -78,6 +94,54 @@ fu_elantp_firmware_parse (FuFirmware *firmware,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_elantp_firmware_build (FuFirmware *firmware, XbNode *n, GError **error)
|
||||
{
|
||||
FuElantpFirmware *self = FU_ELANTP_FIRMWARE (firmware);
|
||||
guint64 tmp;
|
||||
|
||||
/* two simple properties */
|
||||
tmp = xb_node_query_text_as_uint (n, "module_id", NULL);
|
||||
if (tmp != G_MAXUINT64 && tmp <= G_MAXUINT16)
|
||||
self->module_id = tmp;
|
||||
tmp = xb_node_query_text_as_uint (n, "iap_addr", NULL);
|
||||
if (tmp != G_MAXUINT64 && tmp <= G_MAXUINT16)
|
||||
self->iap_addr = tmp;
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_elantp_firmware_write (FuFirmware *firmware, GError **error)
|
||||
{
|
||||
FuElantpFirmware *self = FU_ELANTP_FIRMWARE (firmware);
|
||||
g_autoptr(GByteArray) buf = g_byte_array_new ();
|
||||
g_autoptr(GBytes) blob = NULL;
|
||||
|
||||
/* only one image supported */
|
||||
blob = fu_firmware_get_image_default_bytes (firmware, error);
|
||||
if (blob == NULL)
|
||||
return NULL;
|
||||
|
||||
/* lets build a simple firmware like this:
|
||||
* ------ 0x0
|
||||
* HEADER (containing IAP offset and module ID)
|
||||
* ------ ~0x10a
|
||||
* DATA
|
||||
* ------
|
||||
*/
|
||||
fu_byte_array_set_size (buf, self->iap_addr + 0x2 + 0x2);
|
||||
fu_common_write_uint16 (buf->data + ETP_IAP_START_ADDR_WRDS * 2,
|
||||
self->iap_addr / 2, G_LITTLE_ENDIAN);
|
||||
fu_common_write_uint16 (buf->data + self->iap_addr,
|
||||
(self->iap_addr + 2) / 2, G_LITTLE_ENDIAN);
|
||||
fu_common_write_uint16 (buf->data + self->iap_addr + 0x2,
|
||||
self->module_id, G_LITTLE_ENDIAN);
|
||||
g_byte_array_append (buf, g_bytes_get_data (blob, NULL), g_bytes_get_size (blob));
|
||||
return g_byte_array_free_to_bytes (g_steal_pointer (&buf));
|
||||
}
|
||||
|
||||
static void
|
||||
fu_elantp_firmware_init (FuElantpFirmware *self)
|
||||
{
|
||||
@ -88,6 +152,8 @@ fu_elantp_firmware_class_init (FuElantpFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
|
||||
klass_firmware->parse = fu_elantp_firmware_parse;
|
||||
klass_firmware->build = fu_elantp_firmware_build;
|
||||
klass_firmware->write = fu_elantp_firmware_write;
|
||||
klass_firmware->to_string = fu_elantp_firmware_to_string;
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ shared_module('fu_plugin_elantp',
|
||||
sources : [
|
||||
'fu-plugin-elantp.c',
|
||||
'fu-elantp-common.c',
|
||||
'fu-elantp-firmware.c',
|
||||
'fu-elantp-firmware.c', # fuzzing
|
||||
'fu-elantp-hid-device.c',
|
||||
'fu-elantp-i2c-device.c',
|
||||
],
|
||||
|
7
src/fuzzing/elantp.builder.xml
Normal file
7
src/fuzzing/elantp.builder.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<firmware gtype="FuElantpFirmware">
|
||||
<iap_addr>0xe00</iap_addr>
|
||||
<module_id>0x2</module_id>
|
||||
<image>
|
||||
<data>aGVsbG8gd29ybGQ=</data> <!-- base64 -->
|
||||
</image>
|
||||
</firmware>
|
BIN
src/fuzzing/firmware/elantp.bin
Normal file
BIN
src/fuzzing/firmware/elantp.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user