* [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect
@ 2026-09-23 10:31 Yuanzhe Liu
2026-09-23 10:31 ` [PATCH 1/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on file close after disconnect Yuanzhe Liu
2026-10-30 17:37 ` [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect YuanZhe Liu
0 siblings, 2 replies; 7+ messages in thread
From: Yuanzhe Liu @ 2026-09-23 10:31 UTC (permalink / raw)
To: perex, tiwai; +Cc: linux-sound, linux-kernel, Yuanzhe Liu
Hi,
this single-patch series addresses a slab-use-after-free in the
snd-bcd2000 driver, observed on a Behringer BCD2000 USB DJ controller
under a KASAN-enabled kernel (7.1.2, x86_64, CONFIG_SND_BCD2000=y).
Root-cause walkthrough
----------------------
The bug is a lifetime mismatch between driver disconnect and ALSA rawmidi
file lifetime:
1. A userspace process (e.g. amidi) opens /dev/snd/midiC0D0.
2. The USB interface is unbound (via USBDEVFS_DISCONNECT ioctl or physical
unplug).
3. bcd2000_disconnect() runs:
snd_card_disconnect(bcd2k->card);
bcd2000_free_usb_related_resources(bcd2k, interface);
snd_card_disconnect() only marks the card disconnected and stops new
opens, but returns immediately while open file descriptors still exist.
bcd2000_free_usb_related_resources() proceeds to free both
bcd2k->midi_out_urb and bcd2k->midi_in_urb via usb_free_urb().
4. Later, the process closes the rawmidi fd (or exits):
snd_rawmidi_release -> close_substream -> bcd2000_midi_output_close()
Because bcd2k->midi_out_active was set (and left set by completion
re-submissions), bcd2000_midi_output_close() calls
usb_kill_urb(bcd2k->midi_out_urb), reading the already-freed URB
object (slab-use-after-free at urb->dev).
Patch summary
-------------
Patch 1 fixes the bug via two complementary changes:
- Switch snd_card_disconnect() to snd_card_disconnect_sync(), which
waits for all open card files to be closed before returning. The
rawmidi close callbacks (and their usb_kill_urb()) run while the URBs
are still valid. devices_mutex held during disconnect is not taken by
rawmidi close, so the wait cannot deadlock.
- Add an atomic shutdown flag set at the beginning of disconnect and
checked in bcd2000_midi_send() and both URB completions, preventing
URBs from being re-submitted after disconnect. Also NULL the URB
pointers after usb_free_urb() so any stray access becomes an
immediate NULL dereference rather than a silent UAF.
Crash report addressed
----------------------
Report 1: slab-use-after-free in usb_kill_urb (read of size 8 at urb->dev,
sound/usb/bcd2000/bcd2000.c:182 <- sound/core/rawmidi.c:560).
Condensed splat appended below the diffstat.
Yuanzhe Liu (1):
ALSA: bcd2000: fix use-after-free of MIDI URBs on file close after
disconnect
sound/usb/bcd2000/bcd2000.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
--
Crash excerpt:
BUG: KASAN: slab-use-after-free in usb_kill_urb+0x74/0x80 drivers/usb/core/urb.c:706
Read of size 8 at addr ffff8880078e7d40 by task amidi/30287
Call Trace:
usb_kill_urb+0x74/0x80 drivers/usb/core/urb.c:706
bcd2000_midi_output_close+0xd4/0x140 sound/usb/bcd2000/bcd2000.c:182
close_substream.part.0+0x15f/0x8d0 sound/core/rawmidi.c:560
close_substream sound/core/rawmidi.c:585 [inline]
rawmidi_release_priv+0x21d/0x290 sound/core/rawmidi.c:580
snd_rawmidi_release+0x4e/0xa0 sound/core/rawmidi.c:610
__fput+0x3a6/0xac0 fs/file_table.c:510
task_work_run+0x158/0x220 kernel/task_work.c:233
do_exit+0x87b/0x22d0 kernel/exit.c:976
Allocated by task 34:
usb_alloc_urb+0x67/0x190 drivers/usb/core/urb.c:75
bcd2000_init_midi sound/usb/bcd2000/bcd2000.c:319 [inline]
bcd2000_probe+0x5a0/0x1350 sound/usb/bcd2000/bcd2000.c:401
usb_probe_interface+0x395/0x850 drivers/usb/core/driver.c:396
Freed by task 30294:
usb_free_urb+0xbb/0x100 drivers/usb/core/urb.c:96
bcd2000_free_usb_related_resources sound/usb/bcd2000/bcd2000.c:354 [inline]
bcd2000_disconnect+0xfc/0x280 sound/usb/bcd2000/bcd2000.c:433
usb_unbind_interface+0x188/0x770 drivers/usb/core/driver.c:458
usb_driver_release_interface+0x105/0x180 drivers/usb/core/driver.c:640
proc_ioctl drivers/usb/core/devio.c:2359 [inline]
usbdev_ioctl+0x6f05/0x86d0 drivers/usb/core/devio.c:2826
The buggy address belongs to the object at ffff8880078e7d00
which belongs to the cache kmalloc-192 of size 192
The buggy address is located 64 bytes inside of
freed 192-byte region [ffff8880078e7d00, ffff8880078e7dc0)
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on file close after disconnect
2026-09-23 10:31 [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect Yuanzhe Liu
@ 2026-09-23 10:31 ` Yuanzhe Liu
2026-10-30 17:37 ` [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect YuanZhe Liu
1 sibling, 0 replies; 7+ messages in thread
From: Yuanzhe Liu @ 2026-09-23 10:31 UTC (permalink / raw)
To: perex, tiwai; +Cc: linux-sound, linux-kernel, Yuanzhe Liu, stable
Closing a rawmidi fd of the BCD2000 after its USB interface has been
unbound crashes with a slab-use-after-free in usb_kill_urb():
BUG: KASAN: slab-use-after-free in usb_kill_urb+0x74/0x80
Read of size 8 at addr ffff8880078e7d40 by task amidi/30287
usb_kill_urb+0x74/0x80 drivers/usb/core/urb.c:706
bcd2000_midi_output_close+0xd4/0x140 sound/usb/bcd2000/bcd2000.c:182
close_substream.part.0+0x15f/0x8d0 sound/core/rawmidi.c:560
rawmidi_release_priv+0x21d/0x290 sound/core/rawmidi.c:580
snd_rawmidi_release+0x4e/0xa0 sound/core/rawmidi.c:610
__fput+0x3a6/0xac0 fs/file_table.c:510
Allocated by: usb_alloc_urb <- bcd2000_init_midi <- bcd2000_probe
Freed by: usb_free_urb <- bcd2000_free_usb_related_resources
<- bcd2000_disconnect <- usb_driver_release_interface
<- usbdev_ioctl (USBDEVFS_DISCONNECT)
Root cause: bcd2000_disconnect() calls snd_card_disconnect(), which only
blocks *new* opens, and then immediately kills and frees midi_out_urb and
midi_in_urb. Already-open rawmidi fds, however, keep working: their
->close() callback bcd2000_midi_output_close() unconditionally calls
usb_kill_urb(bcd2k->midi_out_urb) when midi_out_active is set (which it
is, since the completion handler re-submits the out URB), and the URB
completion callbacks re-submit the URBs via bcd2k->midi_{in,out}_urb.
Both dereference pointers that were freed in disconnect -- a UAF. No
physical unplug is needed; USBDEVFS_DISCONNECT on the usbfs node triggers
the same path.
Fix the lifetime mismatch in two parts:
- Wait for the users that are already there: use
snd_card_disconnect_sync() instead of snd_card_disconnect() so that
disconnect blocks until all open card files are released. The rawmidi
close callbacks then run (and call usb_kill_urb()) while the URBs are
still valid, and no userspace-triggered callback can run afterwards.
devices_mutex held by bcd2000_disconnect() is not taken by the rawmidi
close path, so the wait cannot deadlock.
- Mark the device shut down before freeing: add an atomic shutdown flag,
set first in bcd2000_disconnect(), and check it in bcd2000_midi_send()
and in both URB completion handlers so no new URB submission can be
queued while disconnect frees the old ones. Also NULL the URB
pointers after usb_free_urb() so any stray access becomes an
immediate, diagnosable NULL dereference instead of a silent UAF.
Cc: stable@vger.kernel.org
Signed-off-by: Yuanzhe Liu <25031212351@stu.xidian.edu.cn>
---
sound/usb/bcd2000/bcd2000.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index bebb48c..cbf6d39 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -55,6 +55,7 @@ struct bcd2000 {
struct urb *midi_in_urb;
struct usb_anchor anchor;
+ atomic_t shutdown;
};
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -131,7 +132,7 @@ static void bcd2000_midi_send(struct bcd2000 *bcd2k)
BUILD_BUG_ON(sizeof(device_cmd_prefix) >= BUFSIZE);
midi_out_substream = READ_ONCE(bcd2k->midi_out_substream);
- if (!midi_out_substream)
+ if (!midi_out_substream || atomic_read(&bcd2k->shutdown))
return;
/* copy command prefix bytes */
@@ -212,7 +213,7 @@ static void bcd2000_output_complete(struct urb *urb)
dev_warn(&urb->dev->dev,
PREFIX "output urb->status: %d\n", urb->status);
- if (urb->status == -ESHUTDOWN)
+ if (urb->status == -ESHUTDOWN || atomic_read(&bcd2k->shutdown))
return;
/* check if there is more data userspace wants to send */
@@ -228,7 +229,8 @@ static void bcd2000_input_complete(struct urb *urb)
dev_warn(&urb->dev->dev,
PREFIX "input urb->status: %i\n", urb->status);
- if (!bcd2k || urb->status == -ESHUTDOWN)
+ if (!bcd2k || urb->status == -ESHUTDOWN ||
+ atomic_read(&bcd2k->shutdown))
return;
if (urb->actual_length > 0)
@@ -353,6 +355,8 @@ static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k,
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);
@@ -427,8 +431,19 @@ static void bcd2000_disconnect(struct usb_interface *interface)
guard(mutex)(&devices_mutex);
- /* make sure that userspace cannot create new requests */
- snd_card_disconnect(bcd2k->card);
+ /*
+ * Make sure that the URB completion handlers and the rawmidi ops
+ * don't touch the USB device or the URBs any longer.
+ */
+ atomic_set(&bcd2k->shutdown, 1);
+
+ /*
+ * Make sure that userspace cannot create new requests, and wait
+ * until all already-open files are closed so that the rawmidi
+ * close callbacks (which may kill the out URB) run while the
+ * URBs are still valid.
+ */
+ snd_card_disconnect_sync(bcd2k->card);
bcd2000_free_usb_related_resources(bcd2k, interface);
--
2.45.1.windows.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect
2026-09-23 10:31 [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect Yuanzhe Liu
2026-09-23 10:31 ` [PATCH 1/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on file close after disconnect Yuanzhe Liu
@ 2026-10-30 17:37 ` YuanZhe Liu
2026-10-31 18:06 ` Takashi Iwai
1 sibling, 1 reply; 7+ messages in thread
From: YuanZhe Liu @ 2026-10-30 17:37 UTC (permalink / raw)
To: perex, tiwai, Takashi Iwai; +Cc: linux-sound, linux-kernel
Hi Takashi,
Could you please advise on the status of this series and whether any
further work is needed, considering the related upstream fixes?
[PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on
disconnect
The series addresses MIDI URB lifetime on BCD2000 disconnect. I noticed
the related upstream commit below and would appreciate your guidance on
whether this series is still needed.
Related upstream fix:
https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/+/459d3a64766f5ca2f1886daeaf24582831a5f5ab
I am copying this address for visibility.
Original submission:
https://lore.landau.one/lkml/20260923103116.1666-1-25031212351@stu.xidian.edu.cn/T/
Thanks,
YuanZhe
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect
2026-10-30 17:37 ` [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect YuanZhe Liu
@ 2026-10-31 18:06 ` Takashi Iwai
2026-10-31 18:44 ` [PATCH v2] ALSA: bcd2000: Wait for open files before freeing the MIDI URBs YuanZhe Liu
2026-10-31 19:09 ` [PATCH v3] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close YuanZhe Liu
0 siblings, 2 replies; 7+ messages in thread
From: Takashi Iwai @ 2026-10-31 18:06 UTC (permalink / raw)
To: YuanZhe Liu; +Cc: perex, tiwai, Takashi Iwai, linux-sound, linux-kernel
On Fri, 30 Oct 2026 18:37:13 +0100,
YuanZhe Liu wrote:
>
> Hi Takashi,
>
> Could you please advise on the status of this series and whether any
> further work is needed, considering the related upstream fixes?
>
> [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on
> disconnect
>
> The series addresses MIDI URB lifetime on BCD2000 disconnect. I noticed
> the related upstream commit below and would appreciate your guidance on
> whether this series is still needed.
>
> Related upstream fix:
> https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/+/459d3a64766f5ca2f1886daeaf24582831a5f5ab
>
> I am copying this address for visibility.
>
> Original submission:
> https://lore.landau.one/lkml/20260923103116.1666-1-25031212351@stu.xidian.edu.cn/T/
The patch doesn't seem applied cleanly to the latest code.
If the fix is still valid to the latest code, could you rebase and
resubmit?
thanks,
Takashi
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2] ALSA: bcd2000: Wait for open files before freeing the MIDI URBs
2026-10-31 18:06 ` Takashi Iwai
@ 2026-10-31 18:44 ` YuanZhe Liu
2026-10-31 19:09 ` [PATCH v3] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close YuanZhe Liu
1 sibling, 0 replies; 7+ messages in thread
From: YuanZhe Liu @ 2026-10-31 18:44 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai; +Cc: linux-sound, linux-kernel, stable
bcd2000_disconnect() calls snd_card_disconnect(), which only prevents
new opens, and then frees the MIDI URBs. A rawmidi file that was
already open can still be closed afterwards, and its close callback,
bcd2000_midi_output_close(), calls usb_kill_urb() on midi_out_urb.
The URB pointers are cleared on disconnect and their accesses are
serialized with midi_lock, but bcd2000_midi_output_close() reads
midi_out_urb without that lock. The check can therefore pass just
before the pointer is cleared, and usb_kill_urb() then runs on the URB
that has already been freed:
BUG: KASAN: slab-use-after-free in usb_kill_urb+0x74/0x80
Read of size 8 at addr ffff8880078e7d40
usb_kill_urb
bcd2000_midi_output_close
close_substream
rawmidi_release_priv
snd_rawmidi_release
Allocated by: usb_alloc_urb <- bcd2000_init_midi <- bcd2000_probe
Freed by: usb_free_urb <- bcd2000_midi_free
<- bcd2000_disconnect
Use snd_card_disconnect_sync() instead, so that disconnect waits until
all open files are released. The rawmidi close callbacks then run while
the URBs are still valid, and no userspace-triggered callback can run
afterwards. The devices_mutex held by bcd2000_disconnect() is not taken
by the rawmidi close path, so the wait cannot deadlock.
Fixes: b47a22290d58 ("ALSA: MIDI driver for Behringer BCD2000 USB device")
Cc: stable@vger.kernel.org
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
---
v2: rebased onto v7.3-rc7. The URB pointer clearing and the locking are
already handled by 459d3a64766f ("ALSA: bcd2000: clear the URB pointers
on disconnect") and 221253723dc5 ("ALSA: bcd2000: Fix race between
rawmidi and disconnect"), so this version only keeps the change of the
disconnect ordering, as suggested by Takashi Iwai.
sound/usb/bcd2000/bcd2000.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index 2bd49bf82748..a5e8ea92532c 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -451,8 +451,13 @@ static void bcd2000_disconnect(struct usb_interface *interface)
guard(mutex)(&devices_mutex);
- /* make sure that userspace cannot create new requests */
- snd_card_disconnect(bcd2k->card);
+ /*
+ * Make sure that userspace cannot create new requests, and wait
+ * until all already-open files are closed so that the rawmidi
+ * close callbacks (which may kill the out URB) run while the
+ * URBs are still valid.
+ */
+ snd_card_disconnect_sync(bcd2k->card);
bcd2000_free_usb_related_resources(bcd2k, interface);
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close
2026-10-31 18:06 ` Takashi Iwai
2026-10-31 18:44 ` [PATCH v2] ALSA: bcd2000: Wait for open files before freeing the MIDI URBs YuanZhe Liu
@ 2026-10-31 19:09 ` YuanZhe Liu
1 sibling, 0 replies; 7+ messages in thread
From: YuanZhe Liu @ 2026-10-31 19:09 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai
Cc: Bin Yu, Cheng Wen, linux-sound, linux-kernel, stable
bcd2000_disconnect() calls snd_card_disconnect(), which only prevents
new opens, and then frees the MIDI URBs. A rawmidi file that was
already open can still be closed afterwards, and its close callback,
bcd2000_midi_output_close(), calls usb_kill_urb() on midi_out_urb.
The URB pointers are cleared on disconnect and their accesses are
serialized with midi_lock, but bcd2000_midi_output_close() reads
midi_out_urb without that lock. The check can therefore pass just
before the pointer is cleared, and usb_kill_urb() then runs on the URB
that has already been freed:
BUG: KASAN: slab-use-after-free in usb_kill_urb+0x74/0x80
Read of size 8 at addr ffff8880078e7d40
usb_kill_urb
bcd2000_midi_output_close
close_substream
rawmidi_release_priv
snd_rawmidi_release
Allocated by: usb_alloc_urb <- bcd2000_init_midi <- bcd2000_probe
Freed by: usb_free_urb <- bcd2000_midi_free
<- bcd2000_disconnect
Take the lock in bcd2000_midi_output_close() and reference the URB with
usb_get_urb() before releasing it. The URB then stays valid until
usb_put_urb() after usb_kill_urb() has returned, even if a disconnect
frees it in the meantime. usb_kill_urb() itself cannot run under
midi_lock, as the completion handler takes the same lock.
Fixes: b47a22290d58 ("ALSA: MIDI driver for Behringer BCD2000 USB device")
Cc: stable@vger.kernel.org
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
---
v3: reference the URB under midi_lock in bcd2000_midi_output_close()
instead of waiting for open files in bcd2000_disconnect(), which
would block the USB disconnect path on userspace.
sound/usb/bcd2000/bcd2000.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index 2bd49bf82748..0fd086cac955 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -183,10 +183,24 @@ static int bcd2000_midi_output_open(struct snd_rawmidi_substream *substream)
static int bcd2000_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct bcd2000 *bcd2k = substream->rmidi->private_data;
+ struct urb *urb = NULL;
- if (bcd2k->midi_out_active && bcd2k->midi_out_urb) {
- usb_kill_urb(bcd2k->midi_out_urb);
- bcd2k->midi_out_active = 0;
+ /*
+ * Reference the URB under the lock so that it stays valid until
+ * usb_kill_urb() returns, even if a disconnect frees it in the
+ * meantime. usb_kill_urb() cannot run under the lock, as the
+ * completion handler takes the same lock.
+ */
+ scoped_guard(spinlock_irqsave, &bcd2k->midi_lock) {
+ if (bcd2k->midi_out_active && bcd2k->midi_out_urb) {
+ urb = usb_get_urb(bcd2k->midi_out_urb);
+ bcd2k->midi_out_active = 0;
+ }
+ }
+
+ if (urb) {
+ usb_kill_urb(urb);
+ usb_put_urb(urb);
}
return 0;
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect
@ 2026-09-23 10:15 Yuanzhe Liu
0 siblings, 0 replies; 7+ messages in thread
From: Yuanzhe Liu @ 2026-09-23 10:15 UTC (permalink / raw)
To: perex, tiwai; +Cc: linux-sound, linux-kernel, dev, Yuanzhe Liu
Hi,
this single-patch series addresses a slab-use-after-free in the
snd-bcd2000 driver, observed on a Behringer BCD2000 USB DJ controller
under a KASAN-enabled kernel (7.1.2, x86_64, CONFIG_SND_BCD2000=y).
Root-cause walkthrough
----------------------
The bug is a lifetime mismatch between driver disconnect and ALSA rawmidi
file lifetime:
1. A userspace process (e.g. amidi) opens /dev/snd/midiC0D0.
2. The USB interface is unbound (via USBDEVFS_DISCONNECT ioctl or physical
unplug).
3. bcd2000_disconnect() runs:
snd_card_disconnect(bcd2k->card);
bcd2000_free_usb_related_resources(bcd2k, interface);
snd_card_disconnect() only marks the card disconnected and stops new
opens, but returns immediately while open file descriptors still exist.
bcd2000_free_usb_related_resources() proceeds to free both
bcd2k->midi_out_urb and bcd2k->midi_in_urb via usb_free_urb().
4. Later, the process closes the rawmidi fd (or exits):
snd_rawmidi_release -> close_substream -> bcd2000_midi_output_close()
Because bcd2k->midi_out_active was set (and left set by completion
re-submissions), bcd2000_midi_output_close() calls
usb_kill_urb(bcd2k->midi_out_urb), reading the already-freed URB
object (slab-use-after-free at urb->dev).
Patch summary
-------------
Patch 1 fixes the bug via two complementary changes:
- Switch snd_card_disconnect() to snd_card_disconnect_sync(), which
waits for all open card files to be closed before returning. The
rawmidi close callbacks (and their usb_kill_urb()) run while the URBs
are still valid. devices_mutex held during disconnect is not taken by
rawmidi close, so the wait cannot deadlock.
- Add an atomic shutdown flag set at the beginning of disconnect and
checked in bcd2000_midi_send() and both URB completions, preventing
URBs from being re-submitted after disconnect. Also NULL the URB
pointers after usb_free_urb() so any stray access becomes an
immediate NULL dereference rather than a silent UAF.
Crash report addressed
----------------------
Report 1: slab-use-after-free in usb_kill_urb (read of size 8 at urb->dev,
sound/usb/bcd2000/bcd2000.c:182 <- sound/core/rawmidi.c:560).
Condensed splat appended below the diffstat.
Yuanzhe Liu (1):
ALSA: bcd2000: fix use-after-free of MIDI URBs on file close after
disconnect
sound/usb/bcd2000/bcd2000.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
--
Crash excerpt:
BUG: KASAN: slab-use-after-free in usb_kill_urb+0x74/0x80 drivers/usb/core/urb.c:706
Read of size 8 at addr ffff8880078e7d40 by task amidi/30287
Call Trace:
usb_kill_urb+0x74/0x80 drivers/usb/core/urb.c:706
bcd2000_midi_output_close+0xd4/0x140 sound/usb/bcd2000/bcd2000.c:182
close_substream.part.0+0x15f/0x8d0 sound/core/rawmidi.c:560
close_substream sound/core/rawmidi.c:585 [inline]
rawmidi_release_priv+0x21d/0x290 sound/core/rawmidi.c:580
snd_rawmidi_release+0x4e/0xa0 sound/core/rawmidi.c:610
__fput+0x3a6/0xac0 fs/file_table.c:510
task_work_run+0x158/0x220 kernel/task_work.c:233
do_exit+0x87b/0x22d0 kernel/exit.c:976
Allocated by task 34:
usb_alloc_urb+0x67/0x190 drivers/usb/core/urb.c:75
bcd2000_init_midi sound/usb/bcd2000/bcd2000.c:319 [inline]
bcd2000_probe+0x5a0/0x1350 sound/usb/bcd2000/bcd2000.c:401
usb_probe_interface+0x395/0x850 drivers/usb/core/driver.c:396
Freed by task 30294:
usb_free_urb+0xbb/0x100 drivers/usb/core/urb.c:96
bcd2000_free_usb_related_resources sound/usb/bcd2000/bcd2000.c:354 [inline]
bcd2000_disconnect+0xfc/0x280 sound/usb/bcd2000/bcd2000.c:433
usb_unbind_interface+0x188/0x770 drivers/usb/core/driver.c:458
usb_driver_release_interface+0x105/0x180 drivers/usb/core/driver.c:640
proc_ioctl drivers/usb/core/devio.c:2359 [inline]
usbdev_ioctl+0x6f05/0x86d0 drivers/usb/core/devio.c:2826
The buggy address belongs to the object at ffff8880078e7d00
which belongs to the cache kmalloc-192 of size 192
The buggy address is located 64 bytes inside of
freed 192-byte region [ffff8880078e7d00, ffff8880078e7dc0)
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-31 19:09 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23 10:31 [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect Yuanzhe Liu
2026-09-23 10:31 ` [PATCH 1/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on file close after disconnect Yuanzhe Liu
2026-10-30 17:37 ` [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect YuanZhe Liu
2026-10-31 18:06 ` Takashi Iwai
2026-10-31 18:44 ` [PATCH v2] ALSA: bcd2000: Wait for open files before freeing the MIDI URBs YuanZhe Liu
2026-10-31 19:09 ` [PATCH v3] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close YuanZhe Liu
-- strict thread matches above, loose matches on Subject: below --
2026-09-23 10:15 [PATCH 0/1] ALSA: bcd2000: fix use-after-free of MIDI URBs on disconnect Yuanzhe Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®