diff options
author | Kiruthika Varadarajan <Kiruthika.Varadarajan@harman.com> | 2019-06-18 08:39:06 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-14 08:01:10 +0200 |
commit | 9b0bb09062404538800c27ec60442e8fa7c2a0c4 (patch) | |
tree | 444d12596a38e67bb2a495f2fc20ef7cdeb96586 | |
parent | 065700301d513d276cc1612a8993d98475c78aa8 (diff) | |
download | linux-stable-9b0bb09062404538800c27ec60442e8fa7c2a0c4.tar.gz linux-stable-9b0bb09062404538800c27ec60442e8fa7c2a0c4.tar.bz2 linux-stable-9b0bb09062404538800c27ec60442e8fa7c2a0c4.zip |
usb: gadget: ether: Fix race between gether_disconnect and rx_submit
commit d29fcf7078bc8be2b6366cbd4418265b53c94fac upstream.
On spin lock release in rx_submit, gether_disconnect get a chance to
run, it makes port_usb NULL, rx_submit access NULL port USB, hence null
pointer crash.
Fixed by releasing the lock in rx_submit after port_usb is used.
Fixes: 2b3d942c4878 ("usb ethernet gadget: split out network core")
Cc: <stable@vger.kernel.org>
Signed-off-by: Kiruthika Varadarajan <Kiruthika.Varadarajan@harman.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/gadget/function/u_ether.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 737bd77a575d..2929bb47a618 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -186,11 +186,12 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) out = dev->port_usb->out_ep; else out = NULL; - spin_unlock_irqrestore(&dev->lock, flags); if (!out) + { + spin_unlock_irqrestore(&dev->lock, flags); return -ENOTCONN; - + } /* Padding up to RX_EXTRA handles minor disagreements with host. * Normally we use the USB "terminate on short read" convention; @@ -214,6 +215,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) if (dev->port_usb->is_fixed) size = max_t(size_t, size, dev->port_usb->fixed_out_len); + spin_unlock_irqrestore(&dev->lock, flags); skb = __netdev_alloc_skb(dev->net, size + NET_IP_ALIGN, gfp_flags); if (skb == NULL) { |