From de84d964ec587e30d96453af9bd1e9611b5aa910 Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Fri, 5 Mar 2021 11:38:47 +0530 Subject: [PATCH] usb: gsi: Set setup_pending if ep_queue on EP0 is successful Consider a scenario where setup packet gets queued from the function driver and without geting completion for that request composition switch or cable disconnect happens. Since the request is not given back to the gadget driver it will be in pending list. During composition switch or cable disconnect composite dev cleanup happens which will free the request without dequeing it since setup_pending is not set for the request. When a new setup packet is queued and the completion for the new setup packet happens driver will try to access the freed request from the pending list leading to use-after-free. Fix this by setting setup_pending to true if ep_queue on ep0 is successful. Change-Id: I7fe083dfc99663681fc0b98e02613799e526d3d4 Signed-off-by: Pratham Pratap --- drivers/usb/gadget/function/f_gsi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 02aaa3e24b32..1b20e4e53271 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -2091,6 +2091,7 @@ static void gsi_rndis_command_complete(struct usb_ep *ep, struct usb_request *req) { struct f_gsi *gsi = req->context; + struct usb_composite_dev *cdev = gsi->function.config->cdev; int status; u32 MsgType; @@ -2133,6 +2134,7 @@ static void gsi_rndis_command_complete(struct usb_ep *ep, gsi_rndis_flow_ctrl_enable(!(*gsi->params->filter), gsi->params); } + cdev->setup_pending = false; } static void @@ -2182,8 +2184,10 @@ invalid: static void gsi_ctrl_cmd_complete(struct usb_ep *ep, struct usb_request *req) { struct f_gsi *gsi = req->context; + struct usb_composite_dev *cdev = gsi->function.config->cdev; gsi_ctrl_send_cpkt_tomodem(gsi, req->buf, req->actual); + cdev->setup_pending = false; } static void gsi_ctrl_reset_cmd_complete(struct usb_ep *ep, @@ -2403,6 +2407,8 @@ invalid: value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); if (value < 0) log_event_err("response on err %d", value); + else + cdev->setup_pending = true; } /* device either stalls (value < 0) or reports success */