This Linux kernel change "USB: core: Fix unterminated string returned by usb_string()" is included in the Linux 3.16.72 release. This change is authored by Alan Stern <stern [at] rowland.harvard.edu> on Mon Apr 15 11:51:38 2019 -0400. The commit for this change in Linux stable tree is 9dcc2e7 (patch) which is from upstream commit c01c348. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream c01c348.
USB: core: Fix unterminated string returned by usb_string() commit c01c348ecdc66085e44912c97368809612231520 upstream. Some drivers (such as the vub300 MMC driver) expect usb_string() to return a properly NUL-terminated string, even when an error occurs. (In fact, vub300's probe routine doesn't bother to check the return code from usb_string().) When the driver goes on to use an unterminated string, it leads to kernel errors such as stack-out-of-bounds, as found by the syzkaller USB fuzzer. An out-of-range string index argument is not at all unlikely, given that some devices don't provide string descriptors and therefore list 0 as the value for their string indexes. This patch makes usb_string() return a properly terminated empty string along with the -EINVAL error code when an out-of-range index is encountered. And since a USB string index is a single-byte value, indexes >= 256 are just as invalid as values of 0 or below. Signed-off-by: Alan Stern <[email protected]> Reported-by: [email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Ben Hutchings <[email protected]>
There are 4 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.
drivers/usb/core/message.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 6af648c..f7019c7e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -822,9 +822,11 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) if (dev->state == USB_STATE_SUSPENDED) return -EHOSTUNREACH; - if (size <= 0 || !buf || !index) + if (size <= 0 || !buf) return -EINVAL; buf = 0; + if (index <= 0 || index >= 256) + return -EINVAL; tbuf = kmalloc(256, GFP_NOIO); if (!tbuf) return -ENOMEM;