Linux USB
 help / color / mirror / Atom feed
* [PATCH] usb: gadget: f_uac1_legacy: fix double close of the ALSA devices
@ 2026-07-31 18:26 Vasileios Almpanis
  0 siblings, 0 replies; only message in thread
From: Vasileios Almpanis @ 2026-07-31 18:26 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Andrzej Pietrasiewicz, Felipe Balbi
  Cc: linux-usb, linux-kernel, syzbot+df868600fe111c5ff79f,
	Vasileios Almpanis

f_audio_bind() records that the ALSA files are open in the function
instance flag opts->bound, but keeps the file pointers in the
per-function gaudio card. Its error path calls gaudio_cleanup(), which
closes the files without clearing the filp pointers or opts->bound.
A failed bind does not destroy the usb_function, configfs_composite_bind()
puts it back on cfg->func_list, so the next write to UDC binds the same
f_audio, skips gaudio_setup() because opts->bound is still set, and on
failure closes the files a second time. Dropping the config symlink after
a failed bind closes them again via f_audio_free().

BUG: KASAN: slab-use-after-free in filp_flush+0x31/0x190 fs/open.c:1464
Read of size 8 at addr ffff888045f01990 by task syz-executor659/5617
Call Trace:
 filp_close+0x1d/0x40 fs/open.c:1484
 gaudio_close_snd_dev drivers/usb/gadget/function/u_uac1_legacy.c:263 [inline]
 gaudio_cleanup+0x54/0xf0 drivers/usb/gadget/function/u_uac1_legacy.c:305
 f_audio_bind+0x4a0/0x630 drivers/usb/gadget/function/f_uac1_legacy.c:792
 usb_add_function+0x290/0x930 drivers/usb/gadget/composite.c:333
 configfs_composite_bind+0xde0/0x1410 drivers/usb/gadget/configfs.c:1802
 gadget_bind_driver+0x2ca/0x9e0 drivers/usb/gadget/udc/core.c:1662
 gadget_dev_desc_UDC_store+0x1c9/0x2f0 drivers/usb/gadget/configfs.c:300

Clear filp, substream and card in gaudio_close_snd_dev() so cleanup is
idempotent, and close the devices on the bind error path only if that
bind opened them, resetting opts->bound as well.

Fixes: f3a3406b3f56 ("usb: gadget: f_uac1: convert to new function interface with backward compatibility")
Reported-by: syzbot+df868600fe111c5ff79f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=df868600fe111c5ff79f
Signed-off-by: Vasileios Almpanis <vasilisalmpanis@gmail.com>
---
 drivers/usb/gadget/function/f_uac1_legacy.c |  8 +++++++-
 drivers/usb/gadget/function/u_uac1_legacy.c | 17 ++++++++++++++---
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c
index 5d201a2e30e7f19c56c372c9112eb888781bb90d..02774faebdbbc07a3fce0ef1fa47136d34b961ea 100644
--- a/drivers/usb/gadget/function/f_uac1_legacy.c
+++ b/drivers/usb/gadget/function/f_uac1_legacy.c
@@ -732,6 +732,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 	int			status;
 	struct usb_ep		*ep = NULL;
 	struct f_uac1_legacy_opts	*audio_opts;
+	bool			bound_here = false;
 
 	audio_opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst);
 	audio->card.gadget = c->cdev->gadget;
@@ -741,6 +742,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 		if (status < 0)
 			return status;
 		audio_opts->bound = true;
+		bound_here = true;
 	}
 	us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
 	if (IS_ERR(us))
@@ -789,7 +791,11 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 
 fail:
-	gaudio_cleanup(&audio->card);
+	/* Only tear down the ALSA devices if this bind opened them; the */
+	if (bound_here) {
+		gaudio_cleanup(&audio->card);
+		audio_opts->bound = false;
+	}
 	return status;
 }
 
diff --git a/drivers/usb/gadget/function/u_uac1_legacy.c b/drivers/usb/gadget/function/u_uac1_legacy.c
index 01016102fa1728f8bcc92a3ed66b29a318cd52f4..c2b6c88b0bdc9994da027854ec107934c8e814c4 100644
--- a/drivers/usb/gadget/function/u_uac1_legacy.c
+++ b/drivers/usb/gadget/function/u_uac1_legacy.c
@@ -259,18 +259,29 @@ static int gaudio_close_snd_dev(struct gaudio *gau)
 
 	/* Close control device */
 	snd = &gau->control;
-	if (snd->filp)
+	if (snd->filp) {
 		filp_close(snd->filp, NULL);
+		snd->filp = NULL;
+		snd->card = NULL;
+	}
 
 	/* Close PCM playback device and setup substream */
 	snd = &gau->playback;
-	if (snd->filp)
+	if (snd->filp) {
 		filp_close(snd->filp, NULL);
+		snd->filp = NULL;
+		snd->substream = NULL;
+		snd->card = NULL;
+	}
 
 	/* Close PCM capture device and setup substream */
 	snd = &gau->capture;
-	if (snd->filp)
+	if (snd->filp) {
 		filp_close(snd->filp, NULL);
+		snd->filp = NULL;
+		snd->substream = NULL;
+		snd->card = NULL;
+	}
 
 	return 0;
 }

---
base-commit: 8ba098e6b6ff0db8edf28528d1552be261af30d4
change-id: 20260731-alsa-656c9f27b141

Best regards,
-- 
Vasileios Almpanis <vasilisalmpanis@gmail.com>


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-31 18:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-31 18:26 [PATCH] usb: gadget: f_uac1_legacy: fix double close of the ALSA devices Vasileios Almpanis

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