Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef6c8c1d authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

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: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 304ab4ab
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ struct urbtracker {
	struct list_head        urblist_entry;
	struct kref             ref_count;
	struct urb              *urb;
	struct usb_ctrlrequest	*setup;
};

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

	usb_free_urb(urbtrack->urb);
	kfree(urbtrack->setup);
	kfree(urbtrack);
	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;
	int ret_val;
	unsigned long flags;
	struct usb_ctrlrequest setup;
	struct usb_serial *serial = mos_parport->serial;
	struct usb_device *usbdev = serial->dev;

@@ -373,14 +374,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
		kfree(urbtrack);
		return -ENOMEM;
	}
	setup.bRequestType = (__u8)0x40;
	setup.bRequest = (__u8)0x0e;
	setup.wValue = get_reg_value(reg, dummy);
	setup.wIndex = get_reg_index(reg);
	setup.wLength = 0;
	urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
	if (!urbtrack->setup) {
		usb_free_urb(urbtrack->urb);
		kfree(urbtrack);
		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_sndctrlpipe(usbdev, 0),
			     (unsigned char *)&setup,
			     (unsigned char *)urbtrack->setup,
			     NULL, 0, async_complete, urbtrack);
	kref_init(&urbtrack->ref_count);
	INIT_LIST_HEAD(&urbtrack->urblist_entry);