mirror of
https://github.com/S3NEO/android_kernel_samsung_msm8226.git
synced 2024-11-07 03:47:13 +00:00
USB: check usb_get_extra_descriptor for proper size
commit 704620afc70cf47abb9d6a1a57f3825d2bca49cf upstream. When reading an extra descriptor, we need to properly check the minimum and maximum size allowed, to prevent from invalid data being sent by a device. Reported-by: Hui Peng <benquike@gmail.com> Reported-by: Mathias Payer <mathias.payer@nebelwelt.net> Co-developed-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Hui Peng <benquike@gmail.com> Signed-off-by: Mathias Payer <mathias.payer@nebelwelt.net> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> CVE-2018-20169 Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org> Change-Id: I58b9bd1e61a9dd722d99ed05f86f75bd0eb525b4
This commit is contained in:
parent
519ea0fc2a
commit
cd1a4567ba
5 changed files with 8 additions and 8 deletions
|
@ -463,7 +463,7 @@ ccid_bridge_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
ret = __usb_get_extra_descriptor(udev->rawdescriptors[0],
|
||||
le16_to_cpu(udev->config[0].desc.wTotalLength),
|
||||
CCID_CLASS_DECRIPTOR_TYPE, (void **) &buf);
|
||||
CCID_CLASS_DECRIPTOR_TYPE, (void **) &buf, sizeof(*buf));
|
||||
if (ret) {
|
||||
ret = -ENOENT;
|
||||
break;
|
||||
|
|
|
@ -1934,7 +1934,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
|
|||
/* descriptor may appear anywhere in config */
|
||||
if (__usb_get_extra_descriptor (udev->rawdescriptors[0],
|
||||
le16_to_cpu(udev->config[0].desc.wTotalLength),
|
||||
USB_DT_OTG, (void **) &desc) == 0) {
|
||||
USB_DT_OTG, (void **) &desc, sizeof(*desc)) == 0) {
|
||||
if (desc->bmAttributes & USB_OTG_HNP) {
|
||||
unsigned port1 = udev->portnum;
|
||||
|
||||
|
|
|
@ -627,14 +627,14 @@ EXPORT_SYMBOL_GPL(usb_get_current_frame_number);
|
|||
*/
|
||||
|
||||
int __usb_get_extra_descriptor(char *buffer, unsigned size,
|
||||
unsigned char type, void **ptr)
|
||||
unsigned char type, void **ptr, size_t minsize)
|
||||
{
|
||||
struct usb_descriptor_header *header;
|
||||
|
||||
while (size >= sizeof(struct usb_descriptor_header)) {
|
||||
header = (struct usb_descriptor_header *)buffer;
|
||||
|
||||
if (header->bLength < 2) {
|
||||
if (header->bLength < 2 || header->bLength > size) {
|
||||
printk(KERN_ERR
|
||||
"%s: bogus descriptor, type %d length %d\n",
|
||||
usbcore_name,
|
||||
|
@ -643,7 +643,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (header->bDescriptorType == type) {
|
||||
if (header->bDescriptorType == type && header->bLength >= minsize) {
|
||||
*ptr = header;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -614,7 +614,7 @@ static int hwahc_security_create(struct hwahc *hwahc)
|
|||
top = itr + itr_size;
|
||||
result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
|
||||
le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
|
||||
USB_DT_SECURITY, (void **) &secd);
|
||||
USB_DT_SECURITY, (void **) &secd, sizeof(*secd));
|
||||
if (result == -1) {
|
||||
dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
|
||||
return 0;
|
||||
|
|
|
@ -303,11 +303,11 @@ struct usb_host_bos {
|
|||
};
|
||||
|
||||
int __usb_get_extra_descriptor(char *buffer, unsigned size,
|
||||
unsigned char type, void **ptr);
|
||||
unsigned char type, void **ptr, size_t min);
|
||||
#define usb_get_extra_descriptor(ifpoint, type, ptr) \
|
||||
__usb_get_extra_descriptor((ifpoint)->extra, \
|
||||
(ifpoint)->extralen, \
|
||||
type, (void **)ptr)
|
||||
type, (void **)ptr, sizeof(**(ptr)))
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in a new issue