| From 00eb5eb41524007279d6e0e7779c535938177442 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 1 Jul 2021 04:48:34 -0700 |
| Subject: usb: gadget: u_ether: fix a potential null pointer dereference |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Maciej Żenczykowski <maze@google.com> |
| |
| [ Upstream commit 8ae01239609b29ec2eff55967c8e0fe3650cfa09 ] |
| |
| f_ncm tx timeout can call us with null skb to flush |
| a pending frame. In this case skb is NULL to begin |
| with but ceases to be null after dev->wrap() completes. |
| |
| In such a case in->maxpacket will be read, even though |
| we've failed to check that 'in' is not NULL. |
| |
| Though I've never observed this fail in practice, |
| however the 'flush operation' simply does not make sense with |
| a null usb IN endpoint - there's nowhere to flush to... |
| (note that we're the gadget/device, and IN is from the point |
| of view of the host, so here IN actually means outbound...) |
| |
| Cc: Brooke Basile <brookebasile@gmail.com> |
| Cc: "Bryan O'Donoghue" <bryan.odonoghue@linaro.org> |
| Cc: Felipe Balbi <balbi@kernel.org> |
| Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Cc: Lorenzo Colitti <lorenzo@google.com> |
| Signed-off-by: Maciej Żenczykowski <maze@google.com> |
| Link: https://lore.kernel.org/r/20210701114834.884597-6-zenczykowski@gmail.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/usb/gadget/function/u_ether.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c |
| index 989682cc8686..38a35f57b22c 100644 |
| --- a/drivers/usb/gadget/function/u_ether.c |
| +++ b/drivers/usb/gadget/function/u_ether.c |
| @@ -495,8 +495,9 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, |
| } |
| spin_unlock_irqrestore(&dev->lock, flags); |
| |
| - if (skb && !in) { |
| - dev_kfree_skb_any(skb); |
| + if (!in) { |
| + if (skb) |
| + dev_kfree_skb_any(skb); |
| return NETDEV_TX_OK; |
| } |
| |
| -- |
| 2.30.2 |
| |