Skip to content

Commit

Permalink
isight_firmware: Avoid crash on loading invalid firmware
Browse files Browse the repository at this point in the history
Different tools generate slightly different formats of the isight
firmware. Ensure that the firmware buffer is not overrun, while still
ensuring that the correct amount of data is written if trailing data is
present.

Signed-off-by: Matthew Garrett <[email protected]>
Report-by: Justin Mattock <[email protected]>
Tested-by: Justin Mattock <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
mjg59 authored and gregkh committed Jun 12, 2008
1 parent 6460a26 commit 62b5884
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions drivers/usb/misc/isight_firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ static int isight_firmware_load(struct usb_interface *intf,
struct usb_device *dev = interface_to_usbdev(intf);
int llen, len, req, ret = 0;
const struct firmware *firmware;
unsigned char *buf;
unsigned char *buf = kmalloc(50, GFP_KERNEL);
unsigned char data[4];
char *ptr;
u8 *ptr;

if (!buf)
return -ENOMEM;

if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
printk(KERN_ERR "Unable to load isight firmware\n");
Expand All @@ -59,7 +62,7 @@ static int isight_firmware_load(struct usb_interface *intf,
goto out;
}

while (1) {
while (ptr+4 <= firmware->data+firmware->size) {
memcpy(data, ptr, 4);
len = (data[0] << 8 | data[1]);
req = (data[2] << 8 | data[3]);
Expand All @@ -71,10 +74,14 @@ static int isight_firmware_load(struct usb_interface *intf,
continue;

for (; len > 0; req += 50) {
llen = len > 50 ? 50 : len;
llen = min(len, 50);
len -= llen;

buf = kmalloc(llen, GFP_KERNEL);
if (ptr+llen > firmware->data+firmware->size) {
printk(KERN_ERR
"Malformed isight firmware");
ret = -ENODEV;
goto out;
}
memcpy(buf, ptr, llen);

ptr += llen;
Expand All @@ -89,16 +96,18 @@ static int isight_firmware_load(struct usb_interface *intf,
goto out;
}

kfree(buf);
}
}

if (usb_control_msg
(dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
300) != 1) {
printk(KERN_ERR "isight firmware loading completion failed\n");
ret = -ENODEV;
}

out:
kfree(buf);
release_firmware(firmware);
return ret;
}
Expand Down

0 comments on commit 62b5884

Please sign in to comment.