Linux USB
 help / color / mirror / Atom feed
* [PATCH v2] usb: gadget: u_audio: call period elapsed under the stream lock
@ 2026-11-05 11:43 Yaohan Li
  2026-11-05 11:54 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Yaohan Li @ 2026-11-05 11:43 UTC (permalink / raw)
  To: nkapron, gregkh; +Cc: felipe.balbi, vladimir_zapolskiy, linux-usb, linux-kernel

u_audio_iso_complete() drops the substream stream lock before
calling snd_pcm_period_elapsed(), which re-acquires it internally.
Between the unlock and the re-acquire, a concurrent close can run
through snd_pcm_drop(), finish the PCM release and free the runtime,
leaving the period notification to dereference a freed runtime
(runtime->fasync in snd_pcm_period_elapsed()).

Keep the stream lock across the period notification and use
snd_pcm_period_elapsed_under_stream_lock(), the API for exactly this
caller-held-lock case, so the callback's runtime access happens
inside a single locked section.

On final PCM release, snd_pcm_drop() takes the stream lock before
runtime detachment: an in-flight completion holding that lock
finishes before STOP can proceed.  The STOP trigger clears prm->ss,
so subsequent callbacks do not enter the running PCM path.  Runtime
detachment happens later and is not itself protected by the stream
lock.  On the gadget side, u_audio_stop_*() dequeues the requests
before the endpoint is freed.

KASAN reported the use-after-free in u_audio_iso_complete() on the
unmodified kernel.  With the callback stalled inside the locked
section while a concurrent close ran, no use-after-free was reported
after this change.

This issue was investigated and the fix was developed with AI
assistance (ZCode/GLM-4).

Fixes: 773e53d50e227 ("usb: gadget: u_audio: remove cached period bytes value")
Signed-off-by: Yaohan Li <shunsheng1218@gmail.com>
---

Changes since v1:
- v1 saved the period size while the lock was held but still called
  snd_pcm_period_elapsed() after dropping it, leaving the same
  unlock/re-lock window open for the period notification itself.
  This version keeps the stream lock across the notification using
  snd_pcm_period_elapsed_under_stream_lock().
- Documented the synchronization this relies on: snd_pcm_drop()
  takes the stream lock before runtime detachment, so an in-flight
  completion holding the lock finishes first, and its STOP trigger
  clears u_audio's prm->ss so later callbacks take the early exit.
  Runtime detachment itself is not protected by the stream lock.
v1: https://lore.kernel.org/r/179378417544.69464.16164899430939223277@gmail.com/

 drivers/usb/gadget/function/u_audio.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
index f0ee83abcebc7..7da4032e3a203 100644
--- a/drivers/usb/gadget/function/u_audio.c
+++ b/drivers/usb/gadget/function/u_audio.c
@@ -156,6 +156,7 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
 	struct uac_rtd_params *prm = req->context;
 	struct snd_uac_chip *uac = prm->uac;
 	unsigned int frames, p_pktsize;
+	unsigned int period_bytes;
 	unsigned long long pitched_rate_mil, p_pktsize_residue_mil,
 			residue_frames_mil, div_result;
 
@@ -267,10 +268,12 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
 	/* update hw_ptr after data is copied to memory */
 	prm->hw_ptr = (hw_ptr + req->actual) % runtime->dma_bytes;
 	hw_ptr = prm->hw_ptr;
-	snd_pcm_stream_unlock(substream);
+	period_bytes = snd_pcm_lib_period_bytes(substream);
+
+	if ((hw_ptr % period_bytes) < req->actual)
+		snd_pcm_period_elapsed_under_stream_lock(substream);
 
-	if ((hw_ptr % snd_pcm_lib_period_bytes(substream)) < req->actual)
-		snd_pcm_period_elapsed(substream);
+	snd_pcm_stream_unlock(substream);
 
 exit:
 	if (usb_ep_queue(ep, req, GFP_ATOMIC))

base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] usb: gadget: u_audio: call period elapsed under the stream lock
  2026-11-05 11:43 [PATCH v2] usb: gadget: u_audio: call period elapsed under the stream lock Yaohan Li
@ 2026-11-05 11:54 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-11-05 11:54 UTC (permalink / raw)
  To: Yaohan Li; +Cc: linux-usb

> u_audio_iso_complete() drops the substream stream lock before
> calling snd_pcm_period_elapsed(), which re-acquires it internally.
> Between the unlock and the re-acquire, a concurrent close can run
> through snd_pcm_drop(), finish the PCM release and free the runtime,
> leaving the period notification to dereference a freed runtime
> (runtime->fasync in snd_pcm_period_elapsed()).
> 
> Keep the stream lock across the period notification and use
> snd_pcm_period_elapsed_under_stream_lock(), the API for exactly this
> caller-held-lock case, so the callback's runtime access happens
> inside a single locked section.
> 
> On final PCM release, snd_pcm_drop() takes the stream lock before
> runtime detachment: an in-flight completion holding that lock
> finishes before STOP can proceed.  The STOP trigger clears prm->ss,
> so subsequent callbacks do not enter the running PCM path.  Runtime
> detachment happens later and is not itself protected by the stream
> lock.  On the gadget side, u_audio_stop_*() dequeues the requests
> before the endpoint is freed.
> 
> KASAN reported the use-after-free in u_audio_iso_complete() on the
> unmodified kernel.  With the callback stalled inside the locked
> section while a concurrent close ran, no use-after-free was reported
> after this change.
> 
> This issue was investigated and the fix was developed with AI
> assistance (ZCode/GLM-4).
> 
> Fixes: 773e53d50e227 ("usb: gadget: u_audio: remove cached period bytes value")
> Signed-off-by: Yaohan Li <shunsheng1218@gmail.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261105114309.970899-1-shunsheng1218@gmail.com?part=1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-05 11:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-05 11:43 [PATCH v2] usb: gadget: u_audio: call period elapsed under the stream lock Yaohan Li
2026-11-05 11:54 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox