From e9332cf67067ffab07db5814bb4ceee044310275 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Fri, 7 Jan 2022 08:18:15 +0200 Subject: [PATCH] Fixes for midi input - Fix buffer overflow in midi input messages - Detect sysex messages by starting byte instead of length --- src/include/86box/midi.h | 8 ++++---- src/include/86box/snd_mpu401.h | 2 +- src/include/86box/snd_sb_dsp.h | 2 +- src/sound/midi.c | 6 +++--- src/sound/midi_rtmidi.cpp | 6 +++--- src/sound/snd_gus.c | 4 ++-- src/sound/snd_mpu401.c | 4 ++-- src/sound/snd_sb_dsp.c | 8 ++++---- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index e80fe79d6..155965b5a 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -10,7 +10,7 @@ extern uint8_t MIDI_evt_len[256]; extern int midi_device_current; extern int midi_input_device_current; -extern void (*input_msg)(void *p, uint8_t *msg); +extern void (*input_msg)(void *p, uint8_t *msg, uint32_t len); extern int (*input_sysex)(void *p, uint8_t *buf, uint32_t len, int abort); extern void *midi_in_p; @@ -44,7 +44,7 @@ typedef struct midi_in_handler_t int cnt; uint32_t len; - void (*msg)(void *p, uint8_t *msg); + void (*msg)(void *p, uint8_t *msg, uint32_t len); int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort); struct midi_in_handler_t *p; struct midi_in_handler_t *prev, *next; @@ -73,9 +73,9 @@ extern void midi_raw_out_byte(uint8_t val); extern void midi_clear_buffer(void); extern void midi_poll(); -extern void midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p); +extern void midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p); extern void midi_in_handlers_clear(void); -extern void midi_in_msg(uint8_t *msg); +extern void midi_in_msg(uint8_t *msg, uint32_t len); extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #if 0 diff --git a/src/include/86box/snd_mpu401.h b/src/include/86box/snd_mpu401.h index 75eeb8261..93df18a80 100644 --- a/src/include/86box/snd_mpu401.h +++ b/src/include/86box/snd_mpu401.h @@ -159,4 +159,4 @@ extern void mpu401_device_add(void); extern void mpu401_irq_attach(mpu_t *mpu, void (*ext_irq_update)(void *priv, int set), int (*ext_irq_pending)(void *priv), void *priv); extern int MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort); -extern void MPU401_InputMsg(void *p, uint8_t *msg); +extern void MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len); diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index 2e6e7eb8f..067e05b3e 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -102,7 +102,7 @@ typedef struct sb_dsp_t } sb_dsp_t; -void sb_dsp_input_msg(void *p, uint8_t *msg); +void sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len); int sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort); diff --git a/src/sound/midi.c b/src/sound/midi.c index 8a195e2f9..b09e75e78 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -396,7 +396,7 @@ midi_clear_buffer(void) void -midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p) +midi_in_handler(int set, void (*msg)(void *p, uint8_t *msg, uint32_t len), int (*sysex)(void *p, uint8_t *buffer, uint32_t len, int abort), void *p) { midi_in_handler_t *temp = NULL, *next; @@ -479,7 +479,7 @@ midi_in_handlers_clear(void) void -midi_in_msg(uint8_t *msg) +midi_in_msg(uint8_t *msg, uint32_t len) { midi_in_handler_t *temp = mih_first; @@ -488,7 +488,7 @@ midi_in_msg(uint8_t *msg) break; if (temp->msg) - temp->msg(temp->p, msg); + temp->msg(temp->p, msg, len); temp = temp->next; diff --git a/src/sound/midi_rtmidi.cpp b/src/sound/midi_rtmidi.cpp index 50246cac8..b6df5c48b 100644 --- a/src/sound/midi_rtmidi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -145,10 +145,10 @@ rtmidi_get_dev_name(int num, char *s) void rtmidi_input_callback(double timeStamp, std::vector *message, void *userData) { - if (message->size() <= 3) - midi_in_msg(message->data()); + if (message->front() == 0xF0) + midi_in_sysex(message->data(), message->size()); else - midi_in_sysex(message->data(), message->size()); + midi_in_msg(message->data(), message->size()); } diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 003b93b58..afe19bc2a 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -1125,7 +1125,7 @@ static void gus_get_buffer(int32_t *buffer, int len, void *p) gus->pos = 0; } -static void gus_input_msg(void *p, uint8_t *msg) +static void gus_input_msg(void *p, uint8_t *msg, uint32_t len) { gus_t *gus = (gus_t *)p; uint8_t i; @@ -1136,7 +1136,7 @@ static void gus_input_msg(void *p, uint8_t *msg) if (gus->uart_in) { gus->midi_status |= MIDI_INT_RECEIVE; - for (i=0;imidi_queue[gus->midi_w++] = msg[i]; gus->midi_w &= 63; } diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index d79776fb8..1002e72f5 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1422,12 +1422,12 @@ MPU401_InputSysex(void *p, uint8_t *buffer, uint32_t len, int abort) /*Input handler for MIDI*/ void -MPU401_InputMsg(void *p, uint8_t *msg) +MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) { mpu_t *mpu = (mpu_t *)p; int i, tick; static uint8_t old_msg = 0; - uint8_t len = msg[3], key; + uint8_t key; uint8_t recdata[2], recmsg[4]; int send = 1, send_thru = 0; int retrigger_thru = 0, chan, chrefnum; diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index d41467bb5..001d0e94f 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1036,15 +1036,15 @@ sb_read(uint16_t a, void *priv) void -sb_dsp_input_msg(void *p, uint8_t *msg) +sb_dsp_input_msg(void *p, uint8_t *msg, uint32_t len) { sb_dsp_t *dsp = (sb_dsp_t *) p; - uint8_t len = msg[3], i = 0; + uint8_t i = 0; - sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, msg[3]); + sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, len); if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) { - MPU401_InputMsg(dsp->mpu, msg); + MPU401_InputMsg(dsp->mpu, msg, len); return; }