From 9792465ec1d38080fdd5f741694d9acef18bf23e Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 3 May 2020 20:46:10 +0200 Subject: [PATCH] usb_midi: avoid crash if trying to write a partial MIDI event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit thanks to nilsding for investigating! Fixes #15562. Change-Id: I014769afb507881f14f69fb1cd65215dc52920c6 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2048 Reviewed-by: Jérôme Duval --- .../kernel/drivers/midi/usb_midi/usb_midi.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.cpp b/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.cpp index 5656fec2c8..b6b7aace51 100644 --- a/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.cpp +++ b/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.cpp @@ -646,10 +646,18 @@ usb_midi_write(driver_cookie* cookie, off_t position, DPRINTF_DEBUG((MY_ID "MIDI write (%" B_PRIuSIZE " bytes at %" B_PRIdOFF ")\n", *num_bytes, position)); - if (*num_bytes > 3 && midicode != 0xF0) { - DPRINTF_ERR((MY_ID "Non-SysEx packet of %ld bytes" - " -- too big to handle\n", *num_bytes)); - return B_ERROR; + // Make sure we always write exactly one MIDI event at a time. + // SysEx can be of arbitrary sizes, for all others, we check that the + // complete event was passed in and do not use more than that. + // TODO add a loop to allow writing multiple events in a single write() + // call if desired. + if (midicode != 0xF0) { + if (*num_bytes < CINbytes[cin]) { + DPRINTF_ERR((MY_ID "Expected %d bytes for MIDI command %x but got " + "only %d.\n", CINbytes[cin], cin, *num_bytes)); + return B_BAD_DATA; + } + *num_bytes = CINbytes[cin]; } size_t bytes_left = *num_bytes;