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)