[PATCH] media: dvb-frontends: or51132: validate firmware extents

Pengpeng Hou posted 1 patch 3 weeks, 6 days ago
drivers/media/dvb-frontends/or51132.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
[PATCH] media: dvb-frontends: or51132: validate firmware extents
Posted by Pengpeng Hou 3 weeks, 6 days ago
or51132_load_firmware() reads two internal image lengths and passes both
payload ranges to the I2C writer without proving that they fit in the
firmware blob.

Require the size header and both image extents to fit before uploading
firmware.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/media/dvb-frontends/or51132.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c
index e908d33d7e72c..325abaff66a52 100644
--- a/drivers/media/dvb-frontends/or51132.c
+++ b/drivers/media/dvb-frontends/or51132.c
@@ -119,24 +119,30 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
 	struct or51132_state* state = fe->demodulator_priv;
 	static const u8 run_buf[] = {0x7F,0x01};
 	u8 rec_buf[8];
-	u32 firmwareAsize, firmwareBsize;
+	u32 firmware_a_size, firmware_b_size;
 	int i,ret;
 
 	dprintk("Firmware is %zd bytes\n",fw->size);
+	if (fw->size < 8)
+		return -EINVAL;
 
 	/* Get size of firmware A and B */
-	firmwareAsize = le32_to_cpu(*((__le32*)fw->data));
-	dprintk("FirmwareA is %i bytes\n",firmwareAsize);
-	firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4)));
-	dprintk("FirmwareB is %i bytes\n",firmwareBsize);
+	firmware_a_size = le32_to_cpu(*((__le32 *)fw->data));
+	dprintk("FirmwareA is %i bytes\n", firmware_a_size);
+	firmware_b_size = le32_to_cpu(*((__le32 *)(fw->data + 4)));
+	dprintk("FirmwareB is %i bytes\n", firmware_b_size);
+	if (firmware_a_size > fw->size - 8 ||
+	    firmware_b_size > fw->size - 8 - firmware_a_size)
+		return -EINVAL;
 
 	/* Upload firmware */
-	if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) {
+	ret = or51132_writebuf(state, &fw->data[8], firmware_a_size);
+	if (ret) {
 		printk(KERN_WARNING "or51132: load_firmware error 1\n");
 		return ret;
 	}
-	if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize],
-				    firmwareBsize))) {
+	ret = or51132_writebuf(state, &fw->data[8 + firmware_a_size], firmware_b_size);
+	if (ret) {
 		printk(KERN_WARNING "or51132: load_firmware error 2\n");
 		return ret;
 	}

base-commit: 08dbfad3f5040f5bdb6c529da20d6d4e81fefd72
-- 
2.50.1