Skip to content

Commit ef6c8c1

Browse files
jhovoldgregkh
authored andcommitted
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: [email protected] Signed-off-by: Johan Hovold <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 304ab4a commit ef6c8c1

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

drivers/usb/serial/mos7720.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ struct urbtracker {
9090
struct list_head urblist_entry;
9191
struct kref ref_count;
9292
struct urb *urb;
93+
struct usb_ctrlrequest *setup;
9394
};
9495

9596
enum mos7715_pp_modes {
@@ -271,6 +272,7 @@ static void destroy_urbtracker(struct kref *kref)
271272
struct mos7715_parport *mos_parport = urbtrack->mos_parport;
272273

273274
usb_free_urb(urbtrack->urb);
275+
kfree(urbtrack->setup);
274276
kfree(urbtrack);
275277
kref_put(&mos_parport->ref_count, destroy_mos_parport);
276278
}
@@ -355,7 +357,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
355357
struct urbtracker *urbtrack;
356358
int ret_val;
357359
unsigned long flags;
358-
struct usb_ctrlrequest setup;
359360
struct usb_serial *serial = mos_parport->serial;
360361
struct usb_device *usbdev = serial->dev;
361362

@@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
373374
kfree(urbtrack);
374375
return -ENOMEM;
375376
}
376-
setup.bRequestType = (__u8)0x40;
377-
setup.bRequest = (__u8)0x0e;
378-
setup.wValue = get_reg_value(reg, dummy);
379-
setup.wIndex = get_reg_index(reg);
380-
setup.wLength = 0;
377+
urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
378+
if (!urbtrack->setup) {
379+
usb_free_urb(urbtrack->urb);
380+
kfree(urbtrack);
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;
381388
usb_fill_control_urb(urbtrack->urb, usbdev,
382389
usb_sndctrlpipe(usbdev, 0),
383-
(unsigned char *)&setup,
390+
(unsigned char *)urbtrack->setup,
384391
NULL, 0, async_complete, urbtrack);
385392
kref_init(&urbtrack->ref_count);
386393
INIT_LIST_HEAD(&urbtrack->urblist_entry);

0 commit comments

Comments
 (0)