| From 433e104b7a7c36a4de2e72d38f45efa8f8e90fcc Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Mon, 9 Mar 2020 10:59:22 +0100 |
| Subject: [PATCH] ALSA: line6: Fix endless MIDI read loop |
| |
| commit d683469b3c93d7e2afd39e6e1970f24700eb7a68 upstream. |
| |
| The MIDI input event parser of the LINE6 driver may enter into an |
| endless loop when the unexpected data sequence is given, as it tries |
| to continue the secondary bytes without termination. Also, when the |
| input data is too short, the parser returns a negative error, while |
| the caller doesn't handle it properly. This would lead to the |
| unexpected behavior as well. |
| |
| This patch addresses those issues by checking the return value |
| correctly and handling the one-byte event in the parser properly. |
| |
| The bug was reported by syzkaller. |
| |
| Reported-by: syzbot+cce32521ee0a824c21f7@syzkaller.appspotmail.com |
| Cc: <stable@vger.kernel.org> |
| Link: https://lore.kernel.org/r/000000000000033087059f8f8fa3@google.com |
| Link: https://lore.kernel.org/r/20200309095922.30269-1-tiwai@suse.de |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c |
| index e63a2451c88f..b52961076659 100644 |
| --- a/sound/usb/line6/driver.c |
| +++ b/sound/usb/line6/driver.c |
| @@ -316,7 +316,7 @@ static void line6_data_received(struct urb *urb) |
| line6_midibuf_read(mb, line6->buffer_message, |
| LINE6_MIDI_MESSAGE_MAXLEN); |
| |
| - if (done == 0) |
| + if (done <= 0) |
| break; |
| |
| line6->message_length = done; |
| diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c |
| index 8d6eefa0d936..6a70463f82c4 100644 |
| --- a/sound/usb/line6/midibuf.c |
| +++ b/sound/usb/line6/midibuf.c |
| @@ -159,7 +159,7 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data, |
| int midi_length_prev = |
| midibuf_message_length(this->command_prev); |
| |
| - if (midi_length_prev > 0) { |
| + if (midi_length_prev > 1) { |
| midi_length = midi_length_prev - 1; |
| repeat = 1; |
| } else |
| -- |
| 2.7.4 |
| |