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

Commit 58aaa780 authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa Committed by Gerrit - the friendly Code Review server
Browse files

USB: gadget: rndis: Flush rx_work before free_net_dev in cleanup



gether_cleanup() gets called during unbind() and as part of
cleanup, driver flushes work pending and freeing net device. But
it is not flushing pending rx_work. This could cause NULL
pointer access later. Hence flush rx_work before freeing net
device during cleanup to fix the issue.

Also get rndis value from global pointer __rndis under spin lock
in rndis_command_complete/rndis_response_complete callbacks.

Change-Id: Ic2813cf0fff670c12e532b915f6ef2c71df17ddc
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
Signed-off-by: default avatarSivasri Kumar Vanka <sivasri@codeaurora.org>
parent 20775db3
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -446,17 +446,19 @@ static void rndis_response_available(void *_rndis)

static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
{
	struct f_rndis			*rndis = __rndis;
	struct usb_composite_dev	*cdev = rndis->port.func.config->cdev;
	struct f_rndis			*rndis;
	struct usb_composite_dev	*cdev;
	int				status = req->status;
	struct usb_ep *notify_ep;

	spin_lock(&_rndis_lock);
	rndis = __rndis;
	if (!rndis || !rndis->notify) {
		spin_unlock(&_rndis_lock);
		return;
	}

	cdev = rndis->port.func.config->cdev;
	/* after TX:
	 *  - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control)
	 *  - RNDIS_RESPONSE_AVAILABLE (status/irq)
@@ -503,17 +505,19 @@ static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)

static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
{
	struct f_rndis			*rndis = __rndis;
	struct usb_composite_dev	*cdev = rndis->port.func.config->cdev;
	struct f_rndis			*rndis;
	struct usb_composite_dev	*cdev;
	int				status;
	rndis_init_msg_type		*buf;

	spin_lock(&_rndis_lock);
	rndis = __rndis;
	if (!rndis || !rndis->notify) {
		spin_unlock(&_rndis_lock);
		return;
	}

	cdev = rndis->port.func.config->cdev;
	/* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
//	spin_lock(&dev->lock);
	status = rndis_msg_parser(rndis->params, (u8 *) req->buf);
+1 −0
Original line number Diff line number Diff line
@@ -1613,6 +1613,7 @@ void gether_cleanup(struct eth_dev *dev)
	uether_debugfs_exit(dev);
	unregister_netdev(dev->net);
	flush_work(&dev->work);
	cancel_work_sync(&dev->rx_work);
	free_netdev(dev->net);
}
EXPORT_SYMBOL_GPL(gether_cleanup);