1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
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
|