summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2021-07-01 04:48:34 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-22 11:41:24 +0200
commit15c8213699c3db0acdf19d2a87ef8600a89ccd32 (patch)
tree114472df03fc0e7dd89178162c76f018c2a94eb3 /drivers/usb
parent36415d6a02b95a6311b5928c28c362b0d43fdc91 (diff)
usb: gadget: u_ether: fix a potential null pointer dereference
[ 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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/function/u_ether.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index 46c50135ef9f..4bc95ac3d448 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -507,8 +507,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;
}