G'day,
While backporting some stuff from 2.5/linuxconsole CVS to 2.4, I came across
some changes to the way the dev->name string is calculated. I think it can
lead to a one character overflow.
This is an extract from hid-core.c:usb_hid_configure()
<extract>
hid->name[0] = 0;
if (!(buf = kmalloc(64, GFP_KERNEL)))
goto fail;
if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) {
strcat(hid->name, buf);
if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0)
sprintf(hid->name, "%s %s", hid->name, buf);
} else
sprintf(hid->name, "%04x:%04x", dev->descriptor.idVendor,
dev->descriptor.idProduct);
</extract>
The problem is that name is 128 bytes, and given a manufacturer string and a
product string equal to or longer than 64 bytes, I think that the sprintf
will overrun the end of the structure.
The next part of that routine is
<extract>
usb_make_path(dev, buf, 63);
sprintf(hid->phys, "%s/input%d", buf, ifnum);
</extract>
I think that this will overrun too. If the path is longer than 55-47
bytes(depending on the magnitude of ifnum), then it could maybe overrun too.
A patch (that I hope addresses the problem) is attached. Let me know if I've
misunderstood the problem.
Please note - I can't boot 2.5.12, so this has only been tested for
compiliation. Please verify before forwarding.
Brad
diff -Naur -X dontdiff linux-2.5.12/drivers/usb/input/hid-core.c linux-2.5.12-hid-strings/drivers/usb/input/hid-core.c
--- linux-2.5.12/drivers/usb/input/hid-core.c Thu May 2 15:24:25 2002
+++ linux-2.5.12-hid-strings/drivers/usb/input/hid-core.c Fri May 3 15:05:56 2002
@@ -1390,17 +1390,17 @@
hid->name[0] = 0;
- if (!(buf = kmalloc(64, GFP_KERNEL)))
+ if (!(buf = kmalloc(63, GFP_KERNEL)))
goto fail;
- if (usb_string(dev, dev->descriptor.iManufacturer, buf, 64) > 0) {
+ if (usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) {
strcat(hid->name, buf);
- if (usb_string(dev, dev->descriptor.iProduct, buf, 64) > 0)
+ if (usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
sprintf(hid->name, "%s %s", hid->name, buf);
} else
sprintf(hid->name, "%04x:%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
- usb_make_path(dev, buf, 63);
+ usb_make_path(dev, buf, 55);
sprintf(hid->phys, "%s/input%d", buf, ifnum);
if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)