95 lines
2.9 KiB
Diff
95 lines
2.9 KiB
Diff
From 5de53a46283e7c463115444a9339978011dab961 Mon Sep 17 00:00:00 2001
|
|
From: Konstanty Bialkowski <konstanty@ieee.org>
|
|
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; i<n; i++ ) {
|
|
if( h->drum[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; i<n; i++ ) {
|
|
if( h->drum[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
|