Linux Sound subsystem development
 help / color / mirror / Atom feed
* [syzbot] [sound?] [usb?] general protection fault in snd_usbmidi_do_output
@ 2025-09-22 16:54 syzbot
  2025-09-22 23:17 ` [PATCH 1/1] ALSA: usb-audio: Avoid NULL dereference in snd_usbmidi_do_output() Brahmajit Das
  0 siblings, 1 reply; 4+ messages in thread
From: syzbot @ 2025-09-22 16:54 UTC (permalink / raw)
  To: clemens, linux-kernel, linux-sound, linux-usb, perex,
	syzkaller-bugs, tiwai

Hello,

syzbot found the following issue on:

HEAD commit:    3b08f56fbbb9 Merge tag 'x86-urgent-2025-09-20' of git://gi..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=176950e2580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=927198eca77e75d9
dashboard link: https://syzkaller.appspot.com/bug?extid=f02665daa2abeef4a947
compiler:       gcc (Debian 12.2.0-14+deb12u1) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=14006712580000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=14e950e2580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/459cbf9146bd/disk-3b08f56f.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/6836a598801b/vmlinux-3b08f56f.xz
kernel image: https://storage.googleapis.com/syzbot-assets/92e1bc34a72e/bzImage-3b08f56f.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+f02665daa2abeef4a947@syzkaller.appspotmail.com

Oops: general protection fault, probably for non-canonical address 0xdffffc0000000011: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000088-0x000000000000008f]
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/18/2025
RIP: 0010:snd_usbmidi_do_output+0x22d/0x570 sound/usb/midi.c:310
Code: f8 48 c1 e8 03 42 80 3c 28 00 0f 85 14 03 00 00 89 d8 48 c1 e0 04 4c 8b 64 05 08 49 8d 84 24 88 00 00 00 48 89 c2 48 c1 ea 03 <42> 0f b6 14 2a 84 d2 74 09 80 fa 03 0f 8e ad 02 00 00 48 8b 74 24
RSP: 0018:ffffc90000007b80 EFLAGS: 00010016
RAX: 0000000000000088 RBX: 0000000000000000 RCX: ffffffff894338b8
RDX: 0000000000000011 RSI: ffffffff894338c6 RDI: ffff88805e0fc008
RBP: ffff88805e0fc000 R08: 0000000000000005 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: dffffc0000000000 R14: ffffed100bc1f80f R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff8881246b3000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b32d63fff CR3: 000000007e1d5000 CR4: 0000000000350ef0
Call Trace:
 <IRQ>
 snd_usbmidi_error_timer+0x119/0x410 sound/usb/midi.c:362
 call_timer_fn+0x19a/0x620 kernel/time/timer.c:1747
 expire_timers kernel/time/timer.c:1798 [inline]
 __run_timers+0x6ef/0x960 kernel/time/timer.c:2372
 __run_timer_base kernel/time/timer.c:2384 [inline]
 __run_timer_base kernel/time/timer.c:2376 [inline]
 run_timer_base+0x114/0x190 kernel/time/timer.c:2393
 run_timer_softirq+0x1a/0x40 kernel/time/timer.c:2403
 handle_softirqs+0x219/0x8e0 kernel/softirq.c:579
 __do_softirq kernel/softirq.c:613 [inline]
 invoke_softirq kernel/softirq.c:453 [inline]
 __irq_exit_rcu+0x109/0x170 kernel/softirq.c:680
 irq_exit_rcu+0x9/0x30 kernel/softirq.c:696
 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1050 [inline]
 sysvec_apic_timer_interrupt+0xa4/0xc0 arch/x86/kernel/apic/apic.c:1050
 </IRQ>
 <TASK>
 asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702
RIP: 0010:pv_native_safe_halt+0xf/0x20 arch/x86/kernel/paravirt.c:82
Code: 1d 63 02 e9 9e 5a 7d f5 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 66 90 0f 00 2d d3 16 17 00 fb f4 <e9> 77 5a 7d f5 66 2e 0f 1f 84 00 00 00 00 00 66 90 90 90 90 90 90
RSP: 0018:ffffffff8e207e08 EFLAGS: 000002c2
RAX: 00000000000ab2b9 RBX: 0000000000000000 RCX: ffffffff8b92fb49
RDX: 0000000000000000 RSI: ffffffff8de5156d RDI: ffffffff8c163a00
RBP: fffffbfff1c52ef8 R08: 0000000000000001 R09: ffffed1017086655
R10: ffff8880b84332ab R11: 0000000000000000 R12: 0000000000000000
R13: ffffffff8e2977c0 R14: ffffffff90abad90 R15: 0000000000000000
 arch_safe_halt arch/x86/include/asm/paravirt.h:107 [inline]
 default_idle+0x13/0x20 arch/x86/kernel/process.c:757
 default_idle_call+0x6d/0xb0 kernel/sched/idle.c:122
 cpuidle_idle_call kernel/sched/idle.c:190 [inline]
 do_idle+0x391/0x510 kernel/sched/idle.c:330
 cpu_startup_entry+0x4f/0x60 kernel/sched/idle.c:428
 rest_init+0x16b/0x2b0 init/main.c:744
 start_kernel+0x3ee/0x4d0 init/main.c:1097
 x86_64_start_reservations+0x18/0x30 arch/x86/kernel/head64.c:307
 x86_64_start_kernel+0x130/0x190 arch/x86/kernel/head64.c:288
 common_startup_64+0x13e/0x148
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:snd_usbmidi_do_output+0x22d/0x570 sound/usb/midi.c:310
Code: f8 48 c1 e8 03 42 80 3c 28 00 0f 85 14 03 00 00 89 d8 48 c1 e0 04 4c 8b 64 05 08 49 8d 84 24 88 00 00 00 48 89 c2 48 c1 ea 03 <42> 0f b6 14 2a 84 d2 74 09 80 fa 03 0f 8e ad 02 00 00 48 8b 74 24
RSP: 0018:ffffc90000007b80 EFLAGS: 00010016
RAX: 0000000000000088 RBX: 0000000000000000 RCX: ffffffff894338b8
RDX: 0000000000000011 RSI: ffffffff894338c6 RDI: ffff88805e0fc008
RBP: ffff88805e0fc000 R08: 0000000000000005 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: dffffc0000000000 R14: ffffed100bc1f80f R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff8881246b3000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b32d63fff CR3: 000000007e1d5000 CR4: 0000000000350ef0
----------------
Code disassembly (best guess):
   0:	f8                   	clc
   1:	48 c1 e8 03          	shr    $0x3,%rax
   5:	42 80 3c 28 00       	cmpb   $0x0,(%rax,%r13,1)
   a:	0f 85 14 03 00 00    	jne    0x324
  10:	89 d8                	mov    %ebx,%eax
  12:	48 c1 e0 04          	shl    $0x4,%rax
  16:	4c 8b 64 05 08       	mov    0x8(%rbp,%rax,1),%r12
  1b:	49 8d 84 24 88 00 00 	lea    0x88(%r12),%rax
  22:	00
  23:	48 89 c2             	mov    %rax,%rdx
  26:	48 c1 ea 03          	shr    $0x3,%rdx
* 2a:	42 0f b6 14 2a       	movzbl (%rdx,%r13,1),%edx <-- trapping instruction
  2f:	84 d2                	test   %dl,%dl
  31:	74 09                	je     0x3c
  33:	80 fa 03             	cmp    $0x3,%dl
  36:	0f 8e ad 02 00 00    	jle    0x2e9
  3c:	48                   	rex.W
  3d:	8b                   	.byte 0x8b
  3e:	74 24                	je     0x64


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/1] ALSA: usb-audio: Avoid NULL dereference in snd_usbmidi_do_output()
  2025-09-22 16:54 [syzbot] [sound?] [usb?] general protection fault in snd_usbmidi_do_output syzbot
@ 2025-09-22 23:17 ` Brahmajit Das
  2025-09-23  2:40   ` Alan Stern
  0 siblings, 1 reply; 4+ messages in thread
From: Brahmajit Das @ 2025-09-22 23:17 UTC (permalink / raw)
  To: syzbot+f02665daa2abeef4a947
  Cc: clemens, linux-kernel, linux-sound, linux-usb, perex,
	syzkaller-bugs, tiwai

Syzkaller reported a general protection fault in snd_usbmidi_do_output(),
caused by dereferencing a NULL URB pointer when accessing
ep->urbs[urb_index].urb.

This can happen in rare race conditions where the URB was not initialized
or was already freed (e.g. during disconnect or after errors), and the
output timer or other path tries to reuse it.

Fix this by checking if the URB is NULL before accessing it, and skipping
the current slot if it is.

Reported-by: syzbot+f02665daa2abeef4a947@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=f02665daa2abeef4a947

Signed-off-by: Brahmajit Das <listout@listout.xyz>
---
 sound/usb/midi.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index acb3bf92857c..7919a39decb4 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -307,6 +307,10 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
 	for (;;) {
 		if (!(ep->active_urbs & (1 << urb_index))) {
 			urb = ep->urbs[urb_index].urb;
+			if (!urb) {
+				// Skip this urb
+				goto next_urb;
+			}
 			urb->transfer_buffer_length = 0;
 			ep->umidi->usb_protocol_ops->output(ep, urb);
 			if (urb->transfer_buffer_length == 0)
@@ -319,6 +323,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
 				break;
 			ep->active_urbs |= 1 << urb_index;
 		}
+next_urb:
 		if (++urb_index >= OUTPUT_URBS)
 			urb_index = 0;
 		if (urb_index == ep->next_urb)
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/1] ALSA: usb-audio: Avoid NULL dereference in snd_usbmidi_do_output()
  2025-09-22 23:17 ` [PATCH 1/1] ALSA: usb-audio: Avoid NULL dereference in snd_usbmidi_do_output() Brahmajit Das
@ 2025-09-23  2:40   ` Alan Stern
  2025-09-23  6:16     ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: Alan Stern @ 2025-09-23  2:40 UTC (permalink / raw)
  To: Brahmajit Das
  Cc: syzbot+f02665daa2abeef4a947, clemens, linux-kernel, linux-sound,
	linux-usb, perex, syzkaller-bugs, tiwai

On Tue, Sep 23, 2025 at 04:47:20AM +0530, Brahmajit Das wrote:
> Syzkaller reported a general protection fault in snd_usbmidi_do_output(),
> caused by dereferencing a NULL URB pointer when accessing
> ep->urbs[urb_index].urb.
> 
> This can happen in rare race conditions where the URB was not initialized
> or was already freed (e.g. during disconnect or after errors), and the
> output timer or other path tries to reuse it.
> 
> Fix this by checking if the URB is NULL before accessing it, and skipping
> the current slot if it is.
> 
> Reported-by: syzbot+f02665daa2abeef4a947@syzkaller.appspotmail.com
> Link: https://syzkaller.appspot.com/bug?extid=f02665daa2abeef4a947
> 
> Signed-off-by: Brahmajit Das <listout@listout.xyz>
> ---
>  sound/usb/midi.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/sound/usb/midi.c b/sound/usb/midi.c
> index acb3bf92857c..7919a39decb4 100644
> --- a/sound/usb/midi.c
> +++ b/sound/usb/midi.c
> @@ -307,6 +307,10 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
>  	for (;;) {
>  		if (!(ep->active_urbs & (1 << urb_index))) {
>  			urb = ep->urbs[urb_index].urb;
> +			if (!urb) {
> +				// Skip this urb
> +				goto next_urb;
> +			}

What prevents the URB from being freed right here?  If this happens, 
the code below would access memory that was deallocated.

To prevent races, you have to use some sort of lock or other 
synchronization mechanism.  A simple test won't work.

Alan Stern

>  			urb->transfer_buffer_length = 0;
>  			ep->umidi->usb_protocol_ops->output(ep, urb);
>  			if (urb->transfer_buffer_length == 0)
> @@ -319,6 +323,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
>  				break;
>  			ep->active_urbs |= 1 << urb_index;
>  		}
> +next_urb:
>  		if (++urb_index >= OUTPUT_URBS)
>  			urb_index = 0;
>  		if (urb_index == ep->next_urb)
> -- 
> 2.51.0

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/1] ALSA: usb-audio: Avoid NULL dereference in snd_usbmidi_do_output()
  2025-09-23  2:40   ` Alan Stern
@ 2025-09-23  6:16     ` Takashi Iwai
  0 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2025-09-23  6:16 UTC (permalink / raw)
  To: Alan Stern
  Cc: Brahmajit Das, syzbot+f02665daa2abeef4a947, clemens, linux-kernel,
	linux-sound, linux-usb, perex, syzkaller-bugs, tiwai

On Tue, 23 Sep 2025 04:40:13 +0200,
Alan Stern wrote:
> 
> On Tue, Sep 23, 2025 at 04:47:20AM +0530, Brahmajit Das wrote:
> > Syzkaller reported a general protection fault in snd_usbmidi_do_output(),
> > caused by dereferencing a NULL URB pointer when accessing
> > ep->urbs[urb_index].urb.
> > 
> > This can happen in rare race conditions where the URB was not initialized
> > or was already freed (e.g. during disconnect or after errors), and the
> > output timer or other path tries to reuse it.
> > 
> > Fix this by checking if the URB is NULL before accessing it, and skipping
> > the current slot if it is.
> > 
> > Reported-by: syzbot+f02665daa2abeef4a947@syzkaller.appspotmail.com
> > Link: https://syzkaller.appspot.com/bug?extid=f02665daa2abeef4a947
> > 
> > Signed-off-by: Brahmajit Das <listout@listout.xyz>
> > ---
> >  sound/usb/midi.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/sound/usb/midi.c b/sound/usb/midi.c
> > index acb3bf92857c..7919a39decb4 100644
> > --- a/sound/usb/midi.c
> > +++ b/sound/usb/midi.c
> > @@ -307,6 +307,10 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
> >  	for (;;) {
> >  		if (!(ep->active_urbs & (1 << urb_index))) {
> >  			urb = ep->urbs[urb_index].urb;
> > +			if (!urb) {
> > +				// Skip this urb
> > +				goto next_urb;
> > +			}
> 
> What prevents the URB from being freed right here?  If this happens, 
> the code below would access memory that was deallocated.
> 
> To prevent races, you have to use some sort of lock or other 
> synchronization mechanism.  A simple test won't work.

Yes.  The timer instance itself should have been killed before
releasing the resources.

I guess the patch below could cover it, but since I'm traveling, I
can't check it for now.  Will check later once after I'm back.


thanks,

Takashi

--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1511,6 +1511,7 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
 {
 	int i;
 
+	timer_shutdown_sync(&umidi->error_timer);
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
 		struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];
 		if (ep->out)
@@ -1519,7 +1520,6 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
 			snd_usbmidi_in_endpoint_delete(ep->in);
 	}
 	mutex_destroy(&umidi->mutex);
-	timer_shutdown_sync(&umidi->error_timer);
 	kfree(umidi);
 }
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-09-23  6:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-22 16:54 [syzbot] [sound?] [usb?] general protection fault in snd_usbmidi_do_output syzbot
2025-09-22 23:17 ` [PATCH 1/1] ALSA: usb-audio: Avoid NULL dereference in snd_usbmidi_do_output() Brahmajit Das
2025-09-23  2:40   ` Alan Stern
2025-09-23  6:16     ` Takashi Iwai

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