USB: core: Fix unterminated string returned by usb_string() [Linux 4.4.180]

USB: core: Fix unterminated string returned by usb_string() [Linux 4.4.180]

This Linux kernel change "USB: core: Fix unterminated string returned by usb_string()" is included in the Linux 4.4.180 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 b384399 (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 <stern@rowland.harvard.edu>
Reported-by: syzbot+b75b85111c10b8d680f1@syzkaller.appspotmail.com
CC: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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 337658d..adc696a 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -820,9 +820,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] = 0;
+   if (index <= 0 || index >= 256)
+       return -EINVAL;
    tbuf = kmalloc(256, GFP_NOIO);
    if (!tbuf)
        return -ENOMEM;

Leave a Reply

Your email address will not be published. Required fields are marked *