summaryrefslogtreecommitdiff
path: root/extra/libmodplug/libmodplug-CVE-2013-4234-Fix.patch
blob: c4b105d195d78fc6a52d9ffb397efd0c6e3f6a2a (plain)
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