From 5994187764a9ea2a41b26450b74fa53b0970aea1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 25 Mar 2004 01:06:47 -0800 Subject: [PATCH] [PATCH] USB: Don't trust raw descriptor length in devioc. This is a very minor point, unlikely ever to come up. But just in case... It's conceivable that a device might transmit different values for a configuration descriptor's wTotalLength the first time we ask for it (in order to get the length) and the second time (to get the entire descriptor). Should that improbable event occur, the rawdescriptor buffer could be allocated using a size that's smaller than the length recorded in the rawdescriptor itself. This patch protects devio.c against such a problem. If you feel this sequence of events is too unlikely to worry about, then don't bother to apply the patch. --- drivers/usb/core/devio.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 7fdd2df17a124..78bd197cf62e3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -124,14 +124,25 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l unsigned int length = le16_to_cpu(config->wTotalLength); if (*ppos < pos + length) { + + /* The descriptor may claim to be longer than it + * really is. Here is the actual allocated length. */ + unsigned alloclen = + ps->dev->config[i].desc.wTotalLength; + len = length - (*ppos - pos); if (len > nbytes) len = nbytes; - if (copy_to_user(buf, - ps->dev->rawdescriptors[i] + (*ppos - pos), len)) { - ret = -EFAULT; - goto err; + /* Simply don't write (skip over) unallocated parts */ + if (alloclen > (*ppos - pos)) { + alloclen -= (*ppos - pos); + if (copy_to_user(buf, + ps->dev->rawdescriptors[i] + (*ppos - pos), + min(len, alloclen))) { + ret = -EFAULT; + goto err; + } } *ppos += len; -- 2.53.0