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: 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: 85acac61096f9 ("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>

authored by

Ian Abbott and committed by
Greg Kroah-Hartman
cc797d48 3fb43a7a

+19 -16
+19 -16
drivers/comedi/drivers/me_daq.c
··· 344 344 unsigned int file_length; 345 345 unsigned int i; 346 346 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 + 347 366 /* disable irq's on PLX */ 348 367 writel(0x00, devpriv->plx_regbase + PLX9052_INTCSR); 349 368 ··· 375 356 /* Write a dummy value to Xilinx */ 376 357 writeb(0x00, dev->mmio + 0x0); 377 358 sleep(1); 378 - 379 - /* 380 - * Format of the firmware 381 - * Build longs from the byte-wise coded header 382 - * Byte 1-3: length of the array 383 - * Byte 4-7: version 384 - * Byte 8-11: date 385 - * Byte 12-15: reserved 386 - */ 387 - if (size < 16) 388 - return -EINVAL; 389 - 390 - file_length = (((unsigned int)data[0] & 0xff) << 24) + 391 - (((unsigned int)data[1] & 0xff) << 16) + 392 - (((unsigned int)data[2] & 0xff) << 8) + 393 - ((unsigned int)data[3] & 0xff); 394 359 395 360 /* 396 361 * Loop for writing firmware byte by byte to xilinx