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)

Reply via email to