Linux USB
 help / color / mirror / Atom feed
From: Vasileios Almpanis <vasilisalmpanis@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	 Andrzej Pietrasiewicz <andrzej.p@samsung.com>,
	Felipe Balbi <balbi@ti.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	 syzbot+df868600fe111c5ff79f@syzkaller.appspotmail.com,
	 Vasileios Almpanis <vasilisalmpanis@gmail.com>
Subject: [PATCH] usb: gadget: f_uac1_legacy: fix double close of the ALSA devices
Date: Fri, 31 Jul 2026 20:26:45 +0200	[thread overview]
Message-ID: <20260731-alsa-v1-1-95eb93ba32ec@gmail.com> (raw)

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>


                 reply	other threads:[~2026-07-31 18:26 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260731-alsa-v1-1-95eb93ba32ec@gmail.com \
    --to=vasilisalmpanis@gmail.com \
    --cc=andrzej.p@samsung.com \
    --cc=balbi@ti.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=syzbot+df868600fe111c5ff79f@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox