[PATCH] media: validate type 04 Cypress firmware record length

Pengpeng Hou posted 1 patch 1 week, 3 days ago
drivers/media/common/cypress_firmware.c      | 2 ++
drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 2 ++
2 files changed, 4 insertions(+)
[PATCH] media: validate type 04 Cypress firmware record length
Posted by Pengpeng Hou 1 week, 3 days ago
Both Cypress firmware parsers treat an Intel HEX type 04 record as
containing two address bytes, but only validate generic record framing.
A zero-length type 04 record at the end of a firmware blob can make
b[5] read past the blob; a one-byte record makes b[5] refer to the
checksum rather than current record data.

Reject type 04 records shorter than two bytes before reading the
address payload.

The two routines are independent implementations, but they parse the same
Intel HEX type 04 record and fail under the same short-record condition.
Keep the identical validation in one atomic media patch so their
malformed-record behavior cannot diverge.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/media/common/cypress_firmware.c      | 2 ++
 drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/media/common/cypress_firmware.c b/drivers/media/common/cypress_firmware.c
index 66274fdf5243..edbde98b64fe 100644
--- a/drivers/media/common/cypress_firmware.c
+++ b/drivers/media/common/cypress_firmware.c
@@ -59,6 +59,8 @@ static int cypress_get_hexline(const struct firmware *fw,
 	if (hx->type == 0x04) {
 		/* b[4] and b[5] are the Extended linear address record data
 		 * field */
+		if (hx->len < 2)
+			return -EINVAL;
 		hx->addr |= (b[4] << 24) | (b[5] << 16);
 	}
 
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
index 0fb3fa6100e4..0da2e4604c3f 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
@@ -141,6 +141,8 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
 
 	if (hx->type == 0x04) {
 		/* b[4] and b[5] are the Extended linear address record data field */
+		if (hx->len < 2)
+			return -EINVAL;
 		hx->addr |= (b[4] << 24) | (b[5] << 16);
 /*		hx->len -= 2;
 		data_offs += 2; */
-- 
2.43.0