* [PATCH] usb: gadget: u_audio: Fix use-after-free on sound card disconnect
@ 2026-08-10 7:12 Sonali Pradhan
0 siblings, 0 replies; only message in thread
From: Sonali Pradhan @ 2026-08-10 7:12 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Kees Cook, Xu Rao, Alvin Šipraga, John Keeping,
Ruslan Bilovol, stable, linux-usb, linux-kernel, Sonali Pradhan
g_audio_cleanup() invokes snd_card_free_when_closed() to initiate sound
card teardown and immediately frees the underlying struct snd_uac_chip
context. However, snd_card_free_when_closed() returns asynchronously
while ALSA control elements (kctls) remain open in userspace.
When userspace control applications access or close these open file
descriptors, kctl callbacks attempt to dereference kctl->private_data
pointing to &uac->c_prm or &uac->p_prm within the freed uac structure,
resulting in a use-after-free (UAF) memory corruption.
Fix this issue by deferring the destruction of struct snd_uac_chip until
all references to the ALSA sound card are released. Register a custom
card->private_free callback (u_audio_card_free) during g_audio_setup()
that frees uac and its associated playback/capture request and ring
buffers only when the sound card reference count drops to zero.
Fixes: 6c67ed9ad9b8 ("usb: gadget: u_audio: don't let userspace block driver unbind")
Cc: stable@vger.kernel.org
Signed-off-by: Sonali Pradhan <sonalipradhan@google.com>
---
drivers/usb/gadget/function/u_audio.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
index ca26bf9c8040..f0ee83abcebc 100644
--- a/drivers/usb/gadget/function/u_audio.c
+++ b/drivers/usb/gadget/function/u_audio.c
@@ -1183,6 +1183,20 @@ static struct snd_kcontrol_new u_audio_controls[] = {
},
};
+static void u_audio_card_free(struct snd_card *card)
+{
+ struct snd_uac_chip *uac = card->private_data;
+
+ if (!uac)
+ return;
+
+ kfree(uac->p_prm.reqs);
+ kfree(uac->c_prm.reqs);
+ kfree(uac->p_prm.rbuf);
+ kfree(uac->c_prm.rbuf);
+ kfree(uac);
+}
+
int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
const char *card_name)
{
@@ -1262,6 +1276,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
goto fail;
uac->card = card;
+ card->private_data = uac;
+ card->private_free = u_audio_card_free;
/*
* Create first PCM device
@@ -1430,6 +1446,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
snd_fail:
snd_card_free(card);
+ return err;
+
fail:
kfree(uac->p_prm.reqs);
kfree(uac->c_prm.reqs);
@@ -1455,12 +1473,6 @@ void g_audio_cleanup(struct g_audio *g_audio)
card = uac->card;
if (card)
snd_card_free_when_closed(card);
-
- kfree(uac->p_prm.reqs);
- kfree(uac->c_prm.reqs);
- kfree(uac->p_prm.rbuf);
- kfree(uac->c_prm.rbuf);
- kfree(uac);
}
EXPORT_SYMBOL_GPL(g_audio_cleanup);
--
2.55.0.654.g21b8a5bc05-goog
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-10 7:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 7:12 [PATCH] usb: gadget: u_audio: Fix use-after-free on sound card disconnect Sonali Pradhan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox