forked from luck/tmp_suning_uos_patched
USB: mos7720: fix broken control requests
The parallel-port code of the drivers used a stack allocated control-request buffer for asynchronous (and possibly deferred) control requests. This not only violates the no-DMA-from-stack requirement but could also lead to corrupt control requests being submitted. Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
304ab4ab07
commit
ef6c8c1d73
|
@ -90,6 +90,7 @@ struct urbtracker {
|
||||||
struct list_head urblist_entry;
|
struct list_head urblist_entry;
|
||||||
struct kref ref_count;
|
struct kref ref_count;
|
||||||
struct urb *urb;
|
struct urb *urb;
|
||||||
|
struct usb_ctrlrequest *setup;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mos7715_pp_modes {
|
enum mos7715_pp_modes {
|
||||||
|
@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref)
|
||||||
struct mos7715_parport *mos_parport = urbtrack->mos_parport;
|
struct mos7715_parport *mos_parport = urbtrack->mos_parport;
|
||||||
|
|
||||||
usb_free_urb(urbtrack->urb);
|
usb_free_urb(urbtrack->urb);
|
||||||
|
kfree(urbtrack->setup);
|
||||||
kfree(urbtrack);
|
kfree(urbtrack);
|
||||||
kref_put(&mos_parport->ref_count, destroy_mos_parport);
|
kref_put(&mos_parport->ref_count, destroy_mos_parport);
|
||||||
}
|
}
|
||||||
|
@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
||||||
struct urbtracker *urbtrack;
|
struct urbtracker *urbtrack;
|
||||||
int ret_val;
|
int ret_val;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct usb_ctrlrequest setup;
|
|
||||||
struct usb_serial *serial = mos_parport->serial;
|
struct usb_serial *serial = mos_parport->serial;
|
||||||
struct usb_device *usbdev = serial->dev;
|
struct usb_device *usbdev = serial->dev;
|
||||||
|
|
||||||
|
@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
||||||
kfree(urbtrack);
|
kfree(urbtrack);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
setup.bRequestType = (__u8)0x40;
|
urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
|
||||||
setup.bRequest = (__u8)0x0e;
|
if (!urbtrack->setup) {
|
||||||
setup.wValue = get_reg_value(reg, dummy);
|
usb_free_urb(urbtrack->urb);
|
||||||
setup.wIndex = get_reg_index(reg);
|
kfree(urbtrack);
|
||||||
setup.wLength = 0;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
urbtrack->setup->bRequestType = (__u8)0x40;
|
||||||
|
urbtrack->setup->bRequest = (__u8)0x0e;
|
||||||
|
urbtrack->setup->wValue = get_reg_value(reg, dummy);
|
||||||
|
urbtrack->setup->wIndex = get_reg_index(reg);
|
||||||
|
urbtrack->setup->wLength = 0;
|
||||||
usb_fill_control_urb(urbtrack->urb, usbdev,
|
usb_fill_control_urb(urbtrack->urb, usbdev,
|
||||||
usb_sndctrlpipe(usbdev, 0),
|
usb_sndctrlpipe(usbdev, 0),
|
||||||
(unsigned char *)&setup,
|
(unsigned char *)urbtrack->setup,
|
||||||
NULL, 0, async_complete, urbtrack);
|
NULL, 0, async_complete, urbtrack);
|
||||||
kref_init(&urbtrack->ref_count);
|
kref_init(&urbtrack->ref_count);
|
||||||
INIT_LIST_HEAD(&urbtrack->urblist_entry);
|
INIT_LIST_HEAD(&urbtrack->urblist_entry);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user