aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/isight_firmware.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc/isight_firmware.c')
-rw-r--r--drivers/usb/misc/isight_firmware.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c
index 390e04885536..9f30aa1f8a5d 100644
--- a/drivers/usb/misc/isight_firmware.c
+++ b/drivers/usb/misc/isight_firmware.c
@@ -39,9 +39,12 @@ static int isight_firmware_load(struct usb_interface *intf,
39 struct usb_device *dev = interface_to_usbdev(intf); 39 struct usb_device *dev = interface_to_usbdev(intf);
40 int llen, len, req, ret = 0; 40 int llen, len, req, ret = 0;
41 const struct firmware *firmware; 41 const struct firmware *firmware;
42 unsigned char *buf; 42 unsigned char *buf = kmalloc(50, GFP_KERNEL);
43 unsigned char data[4]; 43 unsigned char data[4];
44 char *ptr; 44 u8 *ptr;
45
46 if (!buf)
47 return -ENOMEM;
45 48
46 if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { 49 if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
47 printk(KERN_ERR "Unable to load isight firmware\n"); 50 printk(KERN_ERR "Unable to load isight firmware\n");
@@ -59,7 +62,7 @@ static int isight_firmware_load(struct usb_interface *intf,
59 goto out; 62 goto out;
60 } 63 }
61 64
62 while (1) { 65 while (ptr+4 <= firmware->data+firmware->size) {
63 memcpy(data, ptr, 4); 66 memcpy(data, ptr, 4);
64 len = (data[0] << 8 | data[1]); 67 len = (data[0] << 8 | data[1]);
65 req = (data[2] << 8 | data[3]); 68 req = (data[2] << 8 | data[3]);
@@ -71,10 +74,14 @@ static int isight_firmware_load(struct usb_interface *intf,
71 continue; 74 continue;
72 75
73 for (; len > 0; req += 50) { 76 for (; len > 0; req += 50) {
74 llen = len > 50 ? 50 : len; 77 llen = min(len, 50);
75 len -= llen; 78 len -= llen;
76 79 if (ptr+llen > firmware->data+firmware->size) {
77 buf = kmalloc(llen, GFP_KERNEL); 80 printk(KERN_ERR
81 "Malformed isight firmware");
82 ret = -ENODEV;
83 goto out;
84 }
78 memcpy(buf, ptr, llen); 85 memcpy(buf, ptr, llen);
79 86
80 ptr += llen; 87 ptr += llen;
@@ -89,16 +96,18 @@ static int isight_firmware_load(struct usb_interface *intf,
89 goto out; 96 goto out;
90 } 97 }
91 98
92 kfree(buf);
93 } 99 }
94 } 100 }
101
95 if (usb_control_msg 102 if (usb_control_msg
96 (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, 103 (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
97 300) != 1) { 104 300) != 1) {
98 printk(KERN_ERR "isight firmware loading completion failed\n"); 105 printk(KERN_ERR "isight firmware loading completion failed\n");
99 ret = -ENODEV; 106 ret = -ENODEV;
100 } 107 }
108
101out: 109out:
110 kfree(buf);
102 release_firmware(firmware); 111 release_firmware(firmware);
103 return ret; 112 return ret;
104} 113}