Commit 34bc27e5 authored by Zwane Mwaikambo's avatar Zwane Mwaikambo Committed by Greg Kroah-Hartman

[PATCH] USB core/config.c == memory corruption

parse_interface allocates the incorrect storage size for additional
altsettings (new buffer) leading to a BUG being triggered in
mm/slab.c:1453 when we do the memcpy from the old buffer to the new
buffer (writing beyond new buffer).
Patch appended, tested with an OV511 on an Intel PIIX4
parent e0afb99e
...@@ -109,7 +109,8 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b ...@@ -109,7 +109,8 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b
interface->num_altsetting = 0; interface->num_altsetting = 0;
interface->max_altsetting = USB_ALTSETTINGALLOC; interface->max_altsetting = USB_ALTSETTINGALLOC;
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting,
GFP_KERNEL);
if (!interface->altsetting) { if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting"); err("couldn't kmalloc interface->altsetting");
...@@ -118,29 +119,27 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b ...@@ -118,29 +119,27 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b
while (size > 0) { while (size > 0) {
struct usb_interface_descriptor *d; struct usb_interface_descriptor *d;
if (interface->num_altsetting >= interface->max_altsetting) { if (interface->num_altsetting >= interface->max_altsetting) {
void *ptr; struct usb_host_interface *ptr;
int oldmas; int oldmas;
oldmas = interface->max_altsetting; oldmas = interface->max_altsetting;
interface->max_altsetting += USB_ALTSETTINGALLOC; interface->max_altsetting += USB_ALTSETTINGALLOC;
if (interface->max_altsetting > USB_MAXALTSETTING) { if (interface->max_altsetting > USB_MAXALTSETTING) {
warn("too many alternate settings (max %d)", warn("too many alternate settings (incr %d max %d)\n",
USB_MAXALTSETTING); USB_ALTSETTINGALLOC, USB_MAXALTSETTING);
return -1; return -1;
} }
ptr = interface->altsetting; ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL);
interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); if (ptr == NULL) {
if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting"); err("couldn't kmalloc interface->altsetting");
interface->altsetting = ptr;
return -1; return -1;
} }
memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas); memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas);
kfree(interface->altsetting);
kfree(ptr); interface->altsetting = ptr;
} }
ifp = interface->altsetting + interface->num_altsetting; ifp = interface->altsetting + interface->num_altsetting;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment