diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/misc/isight_firmware.c | 23 |
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 | |||
101 | out: | 109 | out: |
110 | kfree(buf); | ||
102 | release_firmware(firmware); | 111 | release_firmware(firmware); |
103 | return ret; | 112 | return ret; |
104 | } | 113 | } |