Do not leak when calling fu_firmware_parse() multiple times

This commit is contained in:
Richard Hughes 2021-11-24 10:12:22 +00:00
parent 019a210c94
commit 0e175181ea
3 changed files with 21 additions and 0 deletions

View File

@ -683,6 +683,13 @@ fu_firmware_parse_full(FuFirmware *self,
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
/* sanity check */
if (fu_firmware_has_flag(self, FU_FIRMWARE_FLAG_DONE_PARSE)) {
g_set_error_literal(error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"firmware object cannot be reused");
return FALSE;
}
if (g_bytes_get_size(fw) == 0) {
g_set_error_literal(error,
FWUPD_ERROR,
@ -691,6 +698,10 @@ fu_firmware_parse_full(FuFirmware *self,
return FALSE;
}
/* any FuFirmware subclass that gets past this point might have allocated memory in
* ->tokenize() or ->parse() and needs to be destroyed before parsing again */
fu_firmware_add_flag(self, FU_FIRMWARE_FLAG_DONE_PARSE);
/* subclassed */
if (klass->tokenize != NULL) {
if (!klass->tokenize(self, fw, flags, error))

View File

@ -108,6 +108,14 @@ struct _FuFirmwareClass {
* Since: 1.5.6
**/
#define FU_FIRMWARE_FLAG_HAS_VID_PID (1u << 3)
/**
* FU_FIRMWARE_FLAG_DONE_PARSE:
*
* The firmware object has been used by fu_firmware_parse_full().
*
* Since: 1.7.3
**/
#define FU_FIRMWARE_FLAG_DONE_PARSE (1u << 4)
/**
* FuFirmwareFlags:

View File

@ -18,6 +18,8 @@ LLVMFuzzerTestOneInput(const guint8 *data, gsize size)
g_setenv("G_DEBUG", "fatal-criticals", FALSE);
ret = fu_firmware_parse(firmware, fw, FWUPD_INSTALL_FLAG_NONE, NULL);
if (!ret && fu_firmware_has_flag(firmware, FU_FIRMWARE_FLAG_HAS_CHECKSUM)) {
g_clear_object(&firmware);
firmware = FU_FIRMWARE(@FIRMWARENEW@());
ret = fu_firmware_parse(firmware,
fw,
FWUPD_INSTALL_FLAG_NO_SEARCH |