Prevent a partial fuzzing DoS when loading corrupt SREC files

The SREC parser attempts to fill 1Mb of data when parsing corrupt data sections
-- which in the static fuzz targets takes a long time. Correctly check that the
data exists to mitigate.

Fixes https://oss-fuzz.com/testcase-detail/6102934106013696
This commit is contained in:
Richard Hughes 2022-09-29 11:42:21 +01:00
parent 66bf03e8eb
commit a8e56396d5

View File

@ -133,6 +133,7 @@ fu_srec_firmware_tokenize_cb(GString *token, guint token_idx, gpointer user_data
FuSrecFirmwareTokenHelper *helper = (FuSrecFirmwareTokenHelper *)user_data;
FuSrecFirmwarePrivate *priv = GET_PRIVATE(helper->self);
g_autoptr(FuSrecFirmwareRecord) rcd = NULL;
gboolean require_data = FALSE;
guint32 rec_addr32;
guint16 rec_addr16;
guint8 addrsz = 0; /* bytes */
@ -230,15 +231,19 @@ fu_srec_firmware_tokenize_cb(GString *token, guint token_idx, gpointer user_data
switch (rec_kind) {
case FU_FIRMWARE_SREC_RECORD_KIND_S0_HEADER:
addrsz = 2;
require_data = TRUE;
break;
case FU_FIRMWARE_SREC_RECORD_KIND_S1_DATA_16:
addrsz = 2;
require_data = TRUE;
break;
case FU_FIRMWARE_SREC_RECORD_KIND_S2_DATA_24:
addrsz = 3;
require_data = TRUE;
break;
case FU_FIRMWARE_SREC_RECORD_KIND_S3_DATA_32:
addrsz = 4;
require_data = TRUE;
break;
case FU_FIRMWARE_SREC_RECORD_KIND_S5_COUNT_16:
addrsz = 2;
@ -306,6 +311,14 @@ fu_srec_firmware_tokenize_cb(GString *token, guint token_idx, gpointer user_data
rec_addr32,
(guint)rec_count - addrsz - 1);
}
if (require_data && rec_count == addrsz) {
g_set_error(error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"S%u required data but not provided",
rec_kind);
return FALSE;
}
/* data */
rcd = fu_srec_firmware_record_new(token_idx + 1, rec_kind, rec_addr32);