From ade991f6b0ec283be1d5047a10aa0171dc7f2b15 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 5 Nov 2020 10:00:02 +0300 Subject: [PATCH] fix integer overflow in midi parser sample count calculation (bug #200) --- src/f_hmi.c | 24 +++++++++++++++++++++++- src/f_hmp.c | 25 ++++++++++++++++++++++++- src/f_midi.c | 31 ++++++++++++++++++++++++++++++- src/f_xmidi.c | 8 ++++++++ 4 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/f_hmi.c b/src/f_hmi.c index 74759a52..fafbfa80 100644 --- a/src/f_hmi.c +++ b/src/f_hmi.c @@ -129,7 +129,7 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { hmi_data += 370; - smallest_delta = 0xffffffff; + smallest_delta = 0x7fffffff; hmi_track_offset[0] = *hmi_data; // To keep Xcode happy @@ -193,6 +193,21 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { } } + if (smallest_delta >= 0x7fffffff) { + //DEBUG + //fprintf(stderr,"CRAZY SMALLEST DELTA %u\n", smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _hmi_end; + } + + if ((float)smallest_delta >= 0x7fffffff / samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // samples_per_delta_f, smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _hmi_end; + } + subtract_delta = smallest_delta; sample_count_f= (((float) smallest_delta * samples_per_delta_f) + sample_remainder); @@ -368,6 +383,13 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { } // convert smallest delta to samples till next + if ((float)smallest_delta >= 0x7fffffff / samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // samples_per_delta_f, smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _hmi_end; + } subtract_delta = smallest_delta; sample_count_f= (((float) smallest_delta * samples_per_delta_f) + sample_remainder); diff --git a/src/f_hmp.c b/src/f_hmp.c index b0278919..44b3c2a2 100644 --- a/src/f_hmp.c +++ b/src/f_hmp.c @@ -196,7 +196,7 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) { chunk_ofs = (uint32_t *) malloc(sizeof(uint32_t) * hmp_chunks); chunk_end = (uint8_t *) malloc(sizeof(uint8_t) * hmp_chunks); - smallest_delta = 0xffffffff; + smallest_delta = 0x7fffffff; // store chunk info for use, and check chunk lengths for (i = 0; i < hmp_chunks; i++) { /* FIXME: add proper size checks!!! */ @@ -255,6 +255,21 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) { chunk_end[i] = 0; } + if (smallest_delta >= 0x7fffffff) { + //DEBUG + //fprintf(stderr,"CRAZY SMALLEST DELTA %u\n", smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _hmp_end; + } + + if ((float)smallest_delta >= 0x7fffffff / samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // samples_per_delta_f, smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _hmp_end; + } + subtract_delta = smallest_delta; sample_count_f = (((float) smallest_delta * samples_per_delta_f) + sample_remainder); @@ -342,6 +357,14 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) { NEXT_CHUNK: continue; } + if ((float)smallest_delta >= 0x7fffffff / samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // samples_per_delta_f, smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _hmp_end; + } + subtract_delta = smallest_delta; sample_count_f= (((float) smallest_delta * samples_per_delta_f) + sample_remainder); diff --git a/src/f_midi.c b/src/f_midi.c index 886ac053..f7fa0363 100644 --- a/src/f_midi.c +++ b/src/f_midi.c @@ -152,7 +152,7 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { track_end = (uint8_t *) malloc(sizeof(uint8_t) * no_tracks); running_event = (uint8_t *) malloc(sizeof(uint8_t) * no_tracks); - smallest_delta = 0xffffffff; + smallest_delta = 0x7fffffff; for (i = 0; i < no_tracks; i++) { if (midi_size < 8) { _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); @@ -230,6 +230,21 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { } } + if (smallest_delta >= 0x7fffffff) { + //DEBUG + //fprintf(stderr,"CRAZY SMALLEST DELTA %u\n", smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _end; + } + + if ((float)smallest_delta >= 0x7fffffff / samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // samples_per_delta_f, smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _end; + } + subtract_delta = smallest_delta; sample_count_f = (((float) smallest_delta * samples_per_delta_f) + sample_remainder); sample_count = (uint32_t) sample_count_f; @@ -310,6 +325,13 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { NEXT_TRACK: continue; } + if ((float)smallest_delta >= 0x7fffffff / samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // samples_per_delta_f, smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _end; + } subtract_delta = smallest_delta; sample_count_f = (((float) smallest_delta * samples_per_delta_f) + sample_remainder); @@ -377,6 +399,13 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { tracks[i]++; track_size[i]--; + if ((float)smallest_delta >= 0x7fffffff / samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // samples_per_delta_f, smallest_delta); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _end; + } sample_count_f = (((float) track_delta[i] * samples_per_delta_f) + sample_remainder); sample_count = (uint32_t) sample_count_f; diff --git a/src/f_xmidi.c b/src/f_xmidi.c index 3614127e..d1026066 100644 --- a/src/f_xmidi.c +++ b/src/f_xmidi.c @@ -228,6 +228,14 @@ struct _mdi *_WM_ParseNewXmi(uint8_t *xmi_data, uint32_t xmi_size) { xmi_tmpdata = xmi_delta; } + if ((float)xmi_tmpdata >= 0x7fffffff / xmi_samples_per_delta_f) { + //DEBUG + //fprintf(stderr,"INTEGER OVERFLOW (samples_per_delta: %f, smallest_delta: %u)\n", + // xmi_samples_per_delta_f, xmi_tmpdata); + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, NULL, 0); + goto _xmi_end; + } + xmi_sample_count_f= (((float) xmi_tmpdata * xmi_samples_per_delta_f) + xmi_sample_remainder); xmi_sample_count = (uint32_t) xmi_sample_count_f;