aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/mos7720.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2013-08-13 07:27:34 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-14 15:49:27 -0400
commitef6c8c1d733e244f0499035be0dabe1f4ed98c6f (patch)
tree613007be3fb6a2d3690defa6d6a5730ea562c24a /drivers/usb/serial/mos7720.c
parent304ab4ab079a8ed03ce39f1d274964a532db036b (diff)
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>
Diffstat (limited to 'drivers/usb/serial/mos7720.c')
-rw-r--r--drivers/usb/serial/mos7720.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 51da424327b0..b01300164fc0 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -90,6 +90,7 @@ struct urbtracker {
90 struct list_head urblist_entry; 90 struct list_head urblist_entry;
91 struct kref ref_count; 91 struct kref ref_count;
92 struct urb *urb; 92 struct urb *urb;
93 struct usb_ctrlrequest *setup;
93}; 94};
94 95
95enum mos7715_pp_modes { 96enum mos7715_pp_modes {
@@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref)
271 struct mos7715_parport *mos_parport = urbtrack->mos_parport; 272 struct mos7715_parport *mos_parport = urbtrack->mos_parport;
272 273
273 usb_free_urb(urbtrack->urb); 274 usb_free_urb(urbtrack->urb);
275 kfree(urbtrack->setup);
274 kfree(urbtrack); 276 kfree(urbtrack);
275 kref_put(&mos_parport->ref_count, destroy_mos_parport); 277 kref_put(&mos_parport->ref_count, destroy_mos_parport);
276} 278}
@@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
355 struct urbtracker *urbtrack; 357 struct urbtracker *urbtrack;
356 int ret_val; 358 int ret_val;
357 unsigned long flags; 359 unsigned long flags;
358 struct usb_ctrlrequest setup;
359 struct usb_serial *serial = mos_parport->serial; 360 struct usb_serial *serial = mos_parport->serial;
360 struct usb_device *usbdev = serial->dev; 361 struct usb_device *usbdev = serial->dev;
361 362
@@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
373 kfree(urbtrack); 374 kfree(urbtrack);
374 return -ENOMEM; 375 return -ENOMEM;
375 } 376 }
376 setup.bRequestType = (__u8)0x40; 377 urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
377 setup.bRequest = (__u8)0x0e; 378 if (!urbtrack->setup) {
378 setup.wValue = get_reg_value(reg, dummy); 379 usb_free_urb(urbtrack->urb);
379 setup.wIndex = get_reg_index(reg); 380 kfree(urbtrack);
380 setup.wLength = 0; 381 return -ENOMEM;
382 }
383 urbtrack->setup->bRequestType = (__u8)0x40;
384 urbtrack->setup->bRequest = (__u8)0x0e;
385 urbtrack->setup->wValue = get_reg_value(reg, dummy);
386 urbtrack->setup->wIndex = get_reg_index(reg);
387 urbtrack->setup->wLength = 0;
381 usb_fill_control_urb(urbtrack->urb, usbdev, 388 usb_fill_control_urb(urbtrack->urb, usbdev,
382 usb_sndctrlpipe(usbdev, 0), 389 usb_sndctrlpipe(usbdev, 0),
383 (unsigned char *)&setup, 390 (unsigned char *)urbtrack->setup,
384 NULL, 0, async_complete, urbtrack); 391 NULL, 0, async_complete, urbtrack);
385 kref_init(&urbtrack->ref_count); 392 kref_init(&urbtrack->ref_count);
386 INIT_LIST_HEAD(&urbtrack->urblist_entry); 393 INIT_LIST_HEAD(&urbtrack->urblist_entry);