u_ether: Handle memory allocation failure case on tx path
With multipacket feature enabled, if the memory allocation for
tx request buffer fails, accessing the req->buf leads to null pointer
dereference crash.
Hence, handle memory alloction failure case and return -ENOMEM.
CRs-Fixed: 490085
Change-Id: Ic5faac8ea7eb056755b03007c48ff085f10afa20
Signed-off-by: Rajkumar Raghupathy <raghup@codeaurora.org>
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index dbffa4e..f828528 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -585,7 +585,7 @@
return cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS;
}
-static void alloc_tx_buffer(struct eth_dev *dev)
+static int alloc_tx_buffer(struct eth_dev *dev)
{
struct list_head *act;
struct usb_request *req;
@@ -602,7 +602,19 @@
if (!req->buf)
req->buf = kmalloc(dev->tx_req_bufsize,
GFP_ATOMIC);
+ if (!req->buf)
+ goto free_buf;
}
+ return 0;
+
+free_buf:
+ /* tx_req_bufsize = 0 retries mem alloc on next eth_start_xmit */
+ dev->tx_req_bufsize = 0;
+ list_for_each(act, &dev->tx_reqs) {
+ req = container_of(act, struct usb_request, list);
+ kfree(req->buf);
+ }
+ return -ENOMEM;
}
static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
@@ -634,8 +646,11 @@
}
/* Allocate memory for tx_reqs to support multi packet transfer */
- if (multi_pkt_xfer && !dev->tx_req_bufsize)
- alloc_tx_buffer(dev);
+ if (multi_pkt_xfer && !dev->tx_req_bufsize) {
+ retval = alloc_tx_buffer(dev);
+ if (retval < 0)
+ return -ENOMEM;
+ }
/* apply outgoing CDC or RNDIS filters */
if (!is_promisc(cdc_filter)) {