On Wed, 25 May 2005 11:54:44 +0100, Ian Abbott <[EMAIL PROTECTED]> wrote:
> > Bug inside bugfix. > > Please see attached patch for 2.6. It might also apply to > 2.4.31-pre2-bk4 with some fuzz, but I haven't tried it. > - if (unicode_size <= 0) > - return; > + if (unicode_size < 0) > + unicode_size = 0; > > for (i = 0; i < unicode_size; ++i) > string[i] = (char)(le16_to_cpu(unicode[i])); I do not like this either. What does happen when the unicode_size is larger than 30? Someone was in a big hurry pushing "security" fix out. But let's fix it properly, shall we? Please see how the math is made more elegant. Plus, all sorts of little bugs were removed. Notice how the last character of the manufacturer's name was always overwritten with space. Now, it's not (unless zero). diff -urp -X dontdiff linux-2.6.12-rc4/drivers/usb/serial/io_edgeport.c linux-2.6.12-rc4-lem/drivers/usb/serial/io_edgeport.c --- linux-2.6.12-rc4/drivers/usb/serial/io_edgeport.c 2005-05-14 00:02:46.000000000 -0700 +++ linux-2.6.12-rc4-lem/drivers/usb/serial/io_edgeport.c 2005-05-25 09:48:28.000000000 -0700 @@ -361,7 +361,7 @@ struct edgeport_port { /* This structure holds all of the individual device information */ struct edgeport_serial { - char name[MAX_NAME_LEN+1]; /* string name of this device */ + char name[MAX_NAME_LEN+2]; /* string name of this device */ struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ @@ -489,7 +489,7 @@ static void get_manufacturing_desc (stru static void get_boot_desc (struct edgeport_serial *edge_serial); static void load_application_firmware (struct edgeport_serial *edge_serial); -static void unicode_to_ascii (char *string, __le16 *unicode, int unicode_size); +static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size); // ************************************************************************ @@ -592,7 +592,7 @@ static void update_edgeport_E2PROM (stru * Get string descriptor from device * * * ************************************************************************/ -static int get_string (struct usb_device *dev, int Id, char *string) +static int get_string (struct usb_device *dev, int Id, char *string, int buflen) { struct usb_string_descriptor StringDesc; struct usb_string_descriptor *pStringDesc; @@ -614,7 +614,7 @@ static int get_string (struct usb_device return 0; } - unicode_to_ascii(string, pStringDesc->wData, pStringDesc->bLength/2-1); + unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); kfree(pStringDesc); return strlen(string); @@ -2789,16 +2789,20 @@ static void change_port_settings (struct * ASCII range, but it's only for debugging... * NOTE: expects the unicode in LE format ****************************************************************************/ -static void unicode_to_ascii (char *string, __le16 *unicode, int unicode_size) +static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size) { int i; - if (unicode_size <= 0) + if (buflen <= 0) /* never happens, but... */ return; + --buflen; /* space for nul */ - for (i = 0; i < unicode_size; ++i) + for (i = 0; i < unicode_size; i++) { + if (i >= buflen) + break; string[i] = (char)(le16_to_cpu(unicode[i])); - string[unicode_size] = 0x00; + } + string[i] = 0x00; } @@ -2828,11 +2832,17 @@ static void get_manufacturing_desc (stru dbg(" BoardRev: %d", edge_serial->manuf_descriptor.BoardRev); dbg(" NumPorts: %d", edge_serial->manuf_descriptor.NumPorts); dbg(" DescDate: %d/%d/%d", edge_serial->manuf_descriptor.DescDate[0], edge_serial->manuf_descriptor.DescDate[1], edge_serial->manuf_descriptor.DescDate[2]+1900); - unicode_to_ascii (string, edge_serial->manuf_descriptor.SerialNumber, edge_serial->manuf_descriptor.SerNumLength/2-1); + unicode_to_ascii(string, 30, + edge_serial->manuf_descriptor.SerialNumber, + edge_serial->manuf_descriptor.SerNumLength/2); dbg(" SerialNumber: %s", string); - unicode_to_ascii (string, edge_serial->manuf_descriptor.AssemblyNumber, edge_serial->manuf_descriptor.AssemblyNumLength/2-1); + unicode_to_ascii(string, 30, + edge_serial->manuf_descriptor.AssemblyNumber, + edge_serial->manuf_descriptor.AssemblyNumLength/2); dbg(" AssemblyNumber: %s", string); - unicode_to_ascii (string, edge_serial->manuf_descriptor.OemAssyNumber, edge_serial->manuf_descriptor.OemAssyNumLength/2-1); + unicode_to_ascii(string, 30, + edge_serial->manuf_descriptor.OemAssyNumber, + edge_serial->manuf_descriptor.OemAssyNumLength/2); dbg(" OemAssyNumber: %s", string); dbg(" UartType: %d", edge_serial->manuf_descriptor.UartType); dbg(" IonPid: %d", edge_serial->manuf_descriptor.IonPid); @@ -2961,11 +2971,11 @@ static int edge_startup (struct usb_seri usb_set_serial_data(serial, edge_serial); /* get the name for the device from the device */ - if ( (i = get_string(dev, dev->descriptor.iManufacturer, &edge_serial->name[0])) != 0) { - edge_serial->name[i-1] = ' '; - } - - get_string(dev, dev->descriptor.iProduct, &edge_serial->name[i]); + i = get_string(dev, dev->descriptor.iManufacturer, + &edge_serial->name[0], MAX_NAME_LEN+1); + edge_serial->name[i++] = ' '; + get_string(dev, dev->descriptor.iProduct, + &edge_serial->name[i], MAX_NAME_LEN+2 - i); dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); All this only goes to show that someone should have used usb_string() instead of having own get_string(). I think I should save this little problem for interviews. It's all about the good taste and good traditions, down to "++i". But most importantly, Ian, I challenge you to find a corner case which the patch above does not process right. Apply to your tree only if you're unable! Otherwise, send me a scenario where it fails. Cheers, -- Pete ------------------------------------------------------- SF.Net email is sponsored by: GoToMeeting - the easiest way to collaborate online with coworkers and clients while avoiding the high cost of travel and communications. There is no equipment to buy and you can meet as often as you want. Try it free.http://ads.osdn.com/?ad_id=7402&alloc_id=16135&op=click _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel