From 5de53a46283e7c463115444a9339978011dab961 Mon Sep 17 00:00:00 2001 From: Konstanty Bialkowski Date: Wed, 14 Aug 2013 15:15:09 +1000 Subject: [PATCH] CVE-2013-4234 Fix Heap overflow in abc_MIDI_drum + abc_MIDI_gchord -- reported by Florian "Agix" Gaultier --- libmodplug/src/load_abc.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/libmodplug/src/load_abc.cpp b/libmodplug/src/load_abc.cpp index ecb7b62..dd9cc6b 100644 --- a/libmodplug/src/load_abc.cpp +++ b/libmodplug/src/load_abc.cpp @@ -3205,27 +3205,33 @@ static void abc_MIDI_chordname(const char *p) static int abc_MIDI_drum(const char *p, ABCHANDLE *h) { char *q; - int i,n,m; + int i, n, m, len; while( isspace(*p) ) p++; if( !strncmp(p,"on",2) && (isspace(p[2]) || p[2] == '\0') ) return 2; if( !strncmp(p,"off",3) && (isspace(p[3]) || p[3] == '\0') ) return 1; - n = 0; + n = 0; len = 0; for( q = h->drum; *p && !isspace(*p); p++ ) { if( !strchr("dz0123456789",*p) ) break; - *q++ = *p; - if( !isdigit(*p) ) { - if( !isdigit(p[1]) ) *q++ = '1'; + *q++ = *p; len++; + if( !isdigit(*p) && len < sizeof(h->drum)-1 ) { + if( !isdigit(p[1]) ) { *q++ = '1'; len ++; } n++; // count the silences too.... } + if (len >= sizeof(h->drum)-1) { + // consume the rest of the input + // definitely enough "drum last state" stored. + while ( *p && !isspace(*p) ) p++; + break; + } } *q = '\0'; q = h->drumins; for( i = 0; idrum[i*2] == 'd' ) { - while( isspace(*p) ) p++; + while( *p && isspace(*p) ) p++; if( !isdigit(*p) ) { m = 0; - while( !isspace(*p) ) p++; + while( *p && !isspace(*p) ) p++; } else p += abc_getnumber(p,&m); @@ -3236,10 +3242,10 @@ static int abc_MIDI_drum(const char *p, ABCHANDLE *h) q = h->drumvol; for( i = 0; idrum[i*2] == 'd' ) { - while( isspace(*p) ) p++; + while( *p && isspace(*p) ) p++; if( !isdigit(*p) ) { m = 0; - while( !isspace(*p) ) p++; + while( *p && !isspace(*p) ) p++; } else p += abc_getnumber(p,&m); @@ -3254,13 +3260,19 @@ static int abc_MIDI_drum(const char *p, ABCHANDLE *h) static int abc_MIDI_gchord(const char *p, ABCHANDLE *h) { char *q; + int len = 0; while( isspace(*p) ) p++; if( !strncmp(p,"on",2) && (isspace(p[2]) || p[2] == '\0') ) return 2; if( !strncmp(p,"off",3) && (isspace(p[3]) || p[3] == '\0') ) return 1; for( q = h->gchord; *p && !isspace(*p); p++ ) { if( !strchr("fbcz0123456789ghijGHIJ",*p) ) break; - *q++ = *p; - if( !isdigit(*p) && !isdigit(p[1]) ) *q++ = '1'; + *q++ = *p; len++; + if( !isdigit(*p) && len < sizeof(h->gchord)-1 && !isdigit(p[1]) ) { *q++ = '1'; len ++; } + if (len >= sizeof(h->gchord)-1) { + // consume the rest of the input + // definitely enough "drum last state" stored. + while ( *p && !isspace(*p) ) p++; + } } *q = '\0'; return 0; -- 1.8.4