From: Baul Lee <baul.lee@xbow.com>
To: perex@perex.cz, tiwai@suse.com
Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
federico.kirschbaum@xbow.com, stable@vger.kernel.org,
Baul Lee <baul.lee@xbow.com>
Subject: [PATCH] ALSA: bcd2000: clear the URB pointers on disconnect
Date: Wed, 5 Aug 2026 10:34:28 +0900 [thread overview]
Message-ID: <20260805013428.38204-1-baul.lee@xbow.com> (raw)
bcd2000_free_usb_related_resources() frees both URBs and leaves the
pointers behind:
usb_kill_urb(bcd2k->midi_out_urb);
usb_kill_urb(bcd2k->midi_in_urb);
usb_free_urb(bcd2k->midi_out_urb);
usb_free_urb(bcd2k->midi_in_urb);
The rawmidi device outlives that call. A substream that is still open
when the device is unplugged reaches bcd2000_midi_send() from the
trigger path on close. That function writes to the freed URB and then
hands it to the USB core:
bcd2k->midi_out_urb->transfer_buffer_length = BUFSIZE;
...
ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_ATOMIC);
usb_kill_urb() does not stop a later submission either, so a submit that
races the disconnect can requeue the URB after it has been reaped.
midi_in_urb is exposed the same way: bcd2000_input_complete() resubmits
it from the completion handler.
KASAN on 7.2.0-rc5 (arm64):
BUG: KASAN: slab-use-after-free in bcd2000_midi_send [snd_bcd2000]
Write of size 4 at addr ffff00001827d388 by task bpoc/168
__asan_store4
bcd2000_midi_send [snd_bcd2000]
bcd2000_midi_output_trigger [snd_bcd2000]
snd_rawmidi_kernel_write1
close_substream.part.0
Freed by task 168:
usb_free_urb
bcd2000_disconnect [snd_bcd2000]
BUG: KASAN: slab-use-after-free in usb_submit_urb
Read of size 8 at addr ffff00001827d3b8 by task bpoc/168
Clear both pointers after freeing and test them on the paths that can
still run. Poison the URBs before freeing them: usb_poison_urb() waits
for a running completion handler and rejects any later submission, so
after it returns the input path is quiesced and only the rawmidi trigger
path can still reach bcd2000_midi_send(). No unpoison is needed; the
URBs are freed on the next line.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Fixes: b47a22290d58 ("ALSA: MIDI driver for Behringer BCD2000 USB device")
Reported-by: Federico Kirschbaum <federico.kirschbaum@xbow.com>
Reported-by: Baul Lee <baul.lee@xbow.com>
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
---
sound/usb/bcd2000/bcd2000.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index bebb48cb9abc..c5c542d17ccc 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -134,6 +134,9 @@ static void bcd2000_midi_send(struct bcd2000 *bcd2k)
if (!midi_out_substream)
return;
+ if (!bcd2k->midi_out_urb)
+ return;
+
/* copy command prefix bytes */
memcpy(bcd2k->midi_out_buf, device_cmd_prefix,
sizeof(device_cmd_prefix));
@@ -178,7 +181,7 @@ static int bcd2000_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct bcd2000 *bcd2k = substream->rmidi->private_data;
- if (bcd2k->midi_out_active) {
+ if (bcd2k->midi_out_active && bcd2k->midi_out_urb) {
usb_kill_urb(bcd2k->midi_out_urb);
bcd2k->midi_out_active = 0;
}
@@ -348,11 +351,13 @@ static int bcd2000_init_midi(struct bcd2000 *bcd2k)
static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k,
struct usb_interface *interface)
{
- usb_kill_urb(bcd2k->midi_out_urb);
- usb_kill_urb(bcd2k->midi_in_urb);
+ usb_poison_urb(bcd2k->midi_out_urb);
+ usb_poison_urb(bcd2k->midi_in_urb);
usb_free_urb(bcd2k->midi_out_urb);
usb_free_urb(bcd2k->midi_in_urb);
+ bcd2k->midi_out_urb = NULL;
+ bcd2k->midi_in_urb = NULL;
if (bcd2k->intf) {
usb_set_intfdata(bcd2k->intf, NULL);
--
2.50.1 (Apple Git-155)
next reply other threads:[~2026-08-05 1:34 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 1:34 Baul Lee [this message]
2026-08-05 7:34 ` [PATCH] ALSA: bcd2000: clear the URB pointers on disconnect Takashi Iwai
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=20260805013428.38204-1-baul.lee@xbow.com \
--to=baul.lee@xbow.com \
--cc=federico.kirschbaum@xbow.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=perex@perex.cz \
--cc=stable@vger.kernel.org \
--cc=tiwai@suse.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.