Skip to content

Commit dfe7f04

Browse files
tiwaigregkh
authored andcommitted
ALSA: seq: Fix races at MIDI encoding in snd_virmidi_output_trigger()
commit 8f22e52 upstream. The sequencer virmidi code has an open race at its output trigger callback: namely, virmidi keeps only one event packet for processing while it doesn't protect for concurrent output trigger calls. snd_virmidi_output_trigger() tries to process the previously unfinished event before starting encoding the given MIDI stream, but this is done without any lock. Meanwhile, if another rawmidi stream starts the output trigger, this proceeds further, and overwrites the event package that is being processed in another thread. This eventually corrupts and may lead to the invalid memory access if the event type is like SYSEX. The fix is just to move the spinlock to cover both the pending event and the new stream. The bug was spotted by a new fuzzer, RaceFuzzer. BugLink: http://lkml.kernel.org/r/[email protected] Reported-by: DaeRyong Jeong <[email protected]> Cc: <[email protected]> Signed-off-by: Takashi Iwai <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e5e9a77 commit dfe7f04

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

sound/core/seq/seq_virmidi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
174174
}
175175
return;
176176
}
177+
spin_lock_irqsave(&substream->runtime->lock, flags);
177178
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
178179
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
179-
return;
180+
goto out;
180181
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
181182
}
182-
spin_lock_irqsave(&substream->runtime->lock, flags);
183183
while (1) {
184184
count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
185185
if (count <= 0)

0 commit comments

Comments
 (0)