Skip to content

Commit cc797d4

Browse files
ian-abbottgregkh
authored andcommitted
comedi: me_daq: Fix potential overrun of firmware buffer
`me2600_xilinx_download()` loads the firmware that was requested by `request_firmware()`. It is possible for it to overrun the source buffer because it blindly trusts the file format. It reads a data stream length from the first 4 bytes into variable `file_length` and reads the data stream contents of length `file_length` from offset 16 onwards. Although it checks that the supplied firmware is at least 16 bytes long, it does not check that it is long enough to contain the data stream. Add a test to ensure that the supplied firmware is long enough to contain the header and the data stream. On failure, log an error and return `-EINVAL`. Fixes: 85acac6 ("Staging: comedi: add me_daq driver") Cc: stable <stable@kernel.org> Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Link: https://patch.msgid.link/20260205140130.76697-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 3fb43a7 commit cc797d4

1 file changed

Lines changed: 19 additions & 16 deletions

File tree

drivers/comedi/drivers/me_daq.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,25 @@ static int me2600_xilinx_download(struct comedi_device *dev,
344344
unsigned int file_length;
345345
unsigned int i;
346346

347+
/*
348+
* Format of the firmware
349+
* Build longs from the byte-wise coded header
350+
* Byte 1-3: length of the array
351+
* Byte 4-7: version
352+
* Byte 8-11: date
353+
* Byte 12-15: reserved
354+
*/
355+
if (size >= 4) {
356+
file_length = (((unsigned int)data[0] & 0xff) << 24) +
357+
(((unsigned int)data[1] & 0xff) << 16) +
358+
(((unsigned int)data[2] & 0xff) << 8) +
359+
((unsigned int)data[3] & 0xff);
360+
}
361+
if (size < 16 || file_length > size - 16) {
362+
dev_err(dev->class_dev, "Firmware length inconsistency\n");
363+
return -EINVAL;
364+
}
365+
347366
/* disable irq's on PLX */
348367
writel(0x00, devpriv->plx_regbase + PLX9052_INTCSR);
349368

@@ -357,22 +376,6 @@ static int me2600_xilinx_download(struct comedi_device *dev,
357376
writeb(0x00, dev->mmio + 0x0);
358377
sleep(1);
359378

360-
/*
361-
* Format of the firmware
362-
* Build longs from the byte-wise coded header
363-
* Byte 1-3: length of the array
364-
* Byte 4-7: version
365-
* Byte 8-11: date
366-
* Byte 12-15: reserved
367-
*/
368-
if (size < 16)
369-
return -EINVAL;
370-
371-
file_length = (((unsigned int)data[0] & 0xff) << 24) +
372-
(((unsigned int)data[1] & 0xff) << 16) +
373-
(((unsigned int)data[2] & 0xff) << 8) +
374-
((unsigned int)data[3] & 0xff);
375-
376379
/*
377380
* Loop for writing firmware byte by byte to xilinx
378381
* Firmware data start at offset 16

0 commit comments

Comments
 (0)