Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: usb_get_string should check the descriptor type

This patch (as1218) fixes a problem with a radio-control joystick used
in the "walkera 4#3" helicopter. This device responds to the initial
Get-String-Descriptor request for string 0 (which is really the list
of supported languages) by sending its config descriptor! The
usb_get_string() routine needs to check whether it got the right
type of descriptor.

Oddly enough, this sort of check is already present in
usb_get_descriptor(). The patch changes the error code from -EPROTO
to -ENODATA, because -EPROTO shows up in so many other contexts to
indicate a hardware failure rather than a firmware error.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Guillermo Jarabo <williamjap@gmail.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

===================================================================

authored by

Alan Stern and committed by
Greg Kroah-Hartman
67f5a4ba 54b9ed35

+8 -3
+8 -3
drivers/usb/core/message.c
··· 653 653 if (result <= 0 && result != -ETIMEDOUT) 654 654 continue; 655 655 if (result > 1 && ((u8 *)buf)[1] != type) { 656 - result = -EPROTO; 656 + result = -ENODATA; 657 657 continue; 658 658 } 659 659 break; ··· 696 696 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 697 697 (USB_DT_STRING << 8) + index, langid, buf, size, 698 698 USB_CTRL_GET_TIMEOUT); 699 - if (!(result == 0 || result == -EPIPE)) 700 - break; 699 + if (result == 0 || result == -EPIPE) 700 + continue; 701 + if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { 702 + result = -ENODATA; 703 + continue; 704 + } 705 + break; 701 706 } 702 707 return result; 703 708 }