Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: rawmidi: Fix kvfree() call in spinlock

At the conversion of locking with guard(), I overlooked that kvfree()
must not be called inside the spinlock unlike kfree(), and this was
caught by syzkaller now.

This patch reverts the conversion partially for restoring the kvfree()
call outside the spinlock. It's not trivial to use guard() in this
context, unfortunately.

Fixes: 84bb065b316e ("ALSA: rawmidi: Use guard() for locking")
Reported-by: syzbot+351f8764833934c68836@syzkaller.appspotmail.com
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Closes: https://lore.kernel.org/6744737b.050a0220.1cc393.007e.GAE@google.com
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20241125142041.16578-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+3 -1
+3 -1
sound/core/rawmidi.c
··· 724 724 newbuf = kvzalloc(params->buffer_size, GFP_KERNEL); 725 725 if (!newbuf) 726 726 return -ENOMEM; 727 - guard(spinlock_irq)(&substream->lock); 727 + spin_lock_irq(&substream->lock); 728 728 if (runtime->buffer_ref) { 729 + spin_unlock_irq(&substream->lock); 729 730 kvfree(newbuf); 730 731 return -EBUSY; 731 732 } ··· 734 733 runtime->buffer = newbuf; 735 734 runtime->buffer_size = params->buffer_size; 736 735 __reset_runtime_ptrs(runtime, is_input); 736 + spin_unlock_irq(&substream->lock); 737 737 kvfree(oldbuf); 738 738 } 739 739 runtime->avail_min = params->avail_min;