Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

comedi: me4000: Fix potential overrun of firmware buffer

`me4000_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.

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`.

Note: The firmware loading was totally broken before commit ac584af59945
("staging: comedi: me4000: fix firmware downloading"), but that is the
most sensible target for this fix.

Fixes: ac584af59945 ("staging: comedi: me4000: fix firmware downloading")
Cc: stable <stable@kernel.org>
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://patch.msgid.link/20260205133949.71722-1-abbotti@mev.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Ian Abbott and committed by
Greg Kroah-Hartman
3fb43a7a 101ab946

+12 -4
+12 -4
drivers/comedi/drivers/me4000.c
··· 315 315 unsigned int val; 316 316 unsigned int i; 317 317 318 + /* Get data stream length from header. */ 319 + if (size >= 4) { 320 + file_length = (((unsigned int)data[0] & 0xff) << 24) + 321 + (((unsigned int)data[1] & 0xff) << 16) + 322 + (((unsigned int)data[2] & 0xff) << 8) + 323 + ((unsigned int)data[3] & 0xff); 324 + } 325 + if (size < 16 || file_length > size - 16) { 326 + dev_err(dev->class_dev, "Firmware length inconsistency\n"); 327 + return -EINVAL; 328 + } 329 + 318 330 if (!xilinx_iobase) 319 331 return -ENODEV; 320 332 ··· 358 346 outl(val, devpriv->plx_regbase + PLX9052_CNTRL); 359 347 360 348 /* Download Xilinx firmware */ 361 - file_length = (((unsigned int)data[0] & 0xff) << 24) + 362 - (((unsigned int)data[1] & 0xff) << 16) + 363 - (((unsigned int)data[2] & 0xff) << 8) + 364 - ((unsigned int)data[3] & 0xff); 365 349 usleep_range(10, 1000); 366 350 367 351 for (i = 0; i < file_length; i++) {