Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de84d964 authored by Pratham Pratap's avatar Pratham Pratap Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarPratham Pratap <prathampratap@codeaurora.org>
parent 8a7d4fed
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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 @@ gsi_ctrl_set_ntb_cmd_complete(struct usb_ep *ep, struct usb_request *req)
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 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
		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 */