Commit 76a7bfc4 authored by Chris Wulff's avatar Chris Wulff Committed by Greg Kroah-Hartman
Browse files

usb: gadget: u_audio: Check return codes from usb_ep_enable and config_ep_by_speed.



These functions can fail if descriptors are malformed, or missing,
for the selected USB speed.

Fixes: eb9fecb9 ("usb: gadget: f_uac2: split out audio core")
Fixes: 24f779da ("usb: gadget: f_uac2/u_audio: add feedback endpoint support")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarChris Wulff <crwulff@gmail.com>
Link: https://lore.kernel.org/r/20240721192314.3532697-2-crwulff@gmail.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 228a953e
Loading
Loading
Loading
Loading
+34 −8
Original line number Diff line number Diff line
@@ -592,16 +592,25 @@ int u_audio_start_capture(struct g_audio *audio_dev)
	struct usb_ep *ep, *ep_fback;
	struct uac_rtd_params *prm;
	struct uac_params *params = &audio_dev->params;
	int req_len, i;
	int req_len, i, ret;

	prm = &uac->c_prm;
	dev_dbg(dev, "start capture with rate %d\n", prm->srate);
	ep = audio_dev->out_ep;
	config_ep_by_speed(gadget, &audio_dev->func, ep);
	ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
	if (ret < 0) {
		dev_err(dev, "config_ep_by_speed for out_ep failed (%d)\n", ret);
		return ret;
	}

	req_len = ep->maxpacket;

	prm->ep_enabled = true;
	usb_ep_enable(ep);
	ret = usb_ep_enable(ep);
	if (ret < 0) {
		dev_err(dev, "usb_ep_enable failed for out_ep (%d)\n", ret);
		return ret;
	}

	for (i = 0; i < params->req_number; i++) {
		if (!prm->reqs[i]) {
@@ -629,9 +638,18 @@ int u_audio_start_capture(struct g_audio *audio_dev)
		return 0;

	/* Setup feedback endpoint */
	config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
	ret = config_ep_by_speed(gadget, &audio_dev->func, ep_fback);
	if (ret < 0) {
		dev_err(dev, "config_ep_by_speed in_ep_fback failed (%d)\n", ret);
		return ret; // TODO: Clean up out_ep
	}

	prm->fb_ep_enabled = true;
	usb_ep_enable(ep_fback);
	ret = usb_ep_enable(ep_fback);
	if (ret < 0) {
		dev_err(dev, "usb_ep_enable failed for in_ep_fback (%d)\n", ret);
		return ret; // TODO: Clean up out_ep
	}
	req_len = ep_fback->maxpacket;

	req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC);
@@ -687,13 +705,17 @@ int u_audio_start_playback(struct g_audio *audio_dev)
	struct uac_params *params = &audio_dev->params;
	unsigned int factor;
	const struct usb_endpoint_descriptor *ep_desc;
	int req_len, i;
	int req_len, i, ret;
	unsigned int p_pktsize;

	prm = &uac->p_prm;
	dev_dbg(dev, "start playback with rate %d\n", prm->srate);
	ep = audio_dev->in_ep;
	config_ep_by_speed(gadget, &audio_dev->func, ep);
	ret = config_ep_by_speed(gadget, &audio_dev->func, ep);
	if (ret < 0) {
		dev_err(dev, "config_ep_by_speed for in_ep failed (%d)\n", ret);
		return ret;
	}

	ep_desc = ep->desc;
	/*
@@ -720,7 +742,11 @@ int u_audio_start_playback(struct g_audio *audio_dev)
	uac->p_residue_mil = 0;

	prm->ep_enabled = true;
	usb_ep_enable(ep);
	ret = usb_ep_enable(ep);
	if (ret < 0) {
		dev_err(dev, "usb_ep_enable failed for in_ep (%d)\n", ret);
		return ret;
	}

	for (i = 0; i < params->req_number; i++) {
		if (!prm->reqs[i]) {