Package: libmodplug
Version: 1:0.8.8.2-3
Severity: normal
Tags: patch
User: [email protected]
Usertags: origin-ubuntu oneiric ubuntu-patch
*** /tmp/tmpNcrGvL
In Ubuntu, the attached patch was applied to fix the security issue:
* SECURITY UPDATE: multiple security issues in ABC loader
- src/load_abc.cpp: fix various issues.
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=d7c36959757fc6c8e4d487be8a72383093d9d26f
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=5d437ad2f741c08fc3862cd4d5157492ead0fe84
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=a13e067a82fa195b1732ad9fb8341c1b0f141bf5
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=22aa681cd12f8547a8866112c7e443166115b701
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=bd5363f31274d6e79b8ace5a94686c9ac6ef415b
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=51f4b152060be23a4514da2a65c83e205bfb21ba
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=56436fac0a37b1746dab594e4aefba9d2bb92e09
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=ad305187322171eab3a66f4b5ce2a067b1580b3e
-
http://modplug-xmms.git.sourceforge.net/git/gitweb.cgi?p=modplug-xmms/modplug-xmms;a=commit;h=497a27ba2555399d7aa243dbb51ca81e4e7a32cf
- CVE-2011-1761
Thanks for considering the patch.
-- System Information:
Debian Release: squeeze/sid
APT prefers natty-updates
APT policy: (500, 'natty-updates'), (500, 'natty-security'), (500,
'natty-proposed'), (500, 'natty')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.38-11-generic (SMP w/4 CPU cores)
Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diff -u libmodplug-0.8.8.2/debian/changelog libmodplug-0.8.8.2/debian/changelog
only in patch2:
unchanged:
--- libmodplug-0.8.8.2.orig/src/load_abc.cpp
+++ libmodplug-0.8.8.2/src/load_abc.cpp
@@ -277,11 +277,45 @@
}
#endif
-
static int abc_isvalidchar(char c) {
return(isalpha(c) || isdigit(c) || isspace(c) || c == '%' || c == ':');
}
+static const char *abc_skipspace(const char *p)
+{
+ while (*p && isspace(*p))
+ p++;
+ return p;
+}
+
+static void abc_extractkeyvalue(char *key, size_t key_max,
+ char *value, size_t value_max, const char *src)
+{
+ while (*src && isspace(*src))
+ src++;
+
+ size_t key_size;
+ for (key_size = 0; key_size < key_max - 1 && *src;) {
+ if (*src == '=') {
+ src++;
+ break;
+ }
+ key[key_size++] = *src++;
+ }
+ while (key_size > 0 && isspace(key[key_size - 1]))
+ key_size--;
+ key[key_size] = '\0';
+
+ while (*src && isspace(*src))
+ src++;
+
+ size_t value_size;
+ for (value_size = 0; value_size < value_max - 1 && *src;)
+ value[value_size++] = *src++;
+ while (value_size > 0 && isspace(value[value_size - 1]))
+ value_size--;
+ value[value_size] = '\0';
+}
static void abc_message(const char *s1, const char *s2)
{
@@ -308,6 +342,7 @@
static uint32_t notelen_notediv_to_ticks(int speed, int len, int div)
{
uint32_t u;
+ if (div == 0) return 0;
u = (ROWSPERNOTE * RESOLUTION * speed * len * global_tempo_factor) / (div * global_tempo_divider);
return u;
}
@@ -454,7 +489,7 @@
if( mmfeof(mmfile) ) return EOF;
b = mmfile->mm[mmfile->pos];
mmfile->pos++;
- if( b=='\r' && mmfile->mm[mmfile->pos] == '\n' ) {
+ if( b=='\r' && !mmfeof(mmfile) && mmfile->mm[mmfile->pos] == '\n' ) {
b = '\n';
mmfile->pos++;
}
@@ -531,21 +566,13 @@
// =============================================================================
{
ABCMACRO *retval;
- const char *p;
- char buf[256],*q;
- for( p=m; *p && isspace(*p); p++ ) ;
- for( q=buf; *p && *p != '='; p++ )
- *q++ = *p;
- if( q != buf )
- while( isspace(q[-1]) ) q--;
- *q = '\0';
+ char key[256], value[256];
+ abc_extractkeyvalue(key, sizeof(key), value, sizeof(value), m);
+
retval = (ABCMACRO *)_mm_calloc(h->macrohandle, 1,sizeof(ABCTRACK));
- retval->name = DupStr(h->macrohandle, buf,strlen(buf));
+ retval->name = DupStr(h->macrohandle, key, strlen(key));
retval->n = strrchr(retval->name, 'n'); // for transposing macro's
- for( p++; *p && isspace(*p); p++ ) ;
- strncpy(buf,p,200);
- for( q=&buf[strlen(buf)-1]; q!=buf && isspace(*q); q-- ) *q = '\0';
- retval->subst = DupStr(h->macrohandle, buf, strlen(buf));
+ retval->subst = DupStr(h->macrohandle, value, strlen(value));
retval->next = h->macro;
h->macro = retval;
}
@@ -555,24 +582,15 @@
// =============================================================================
{
ABCMACRO *retval, *mp;
- const char *p;
- char buf[256], let[2], *q;
- for( p=m; *p && isspace(*p); p++ ) ;
- for( q=buf; *p && *p != '='; p++ )
- *q++ = *p;
- if( q != buf )
- while( isspace(q[-1]) ) q--;
- *q = '\0';
- if( strlen(buf) > 1 || strchr("~HIJKLMNOPQRSTUVWXY",toupper(buf[0])) == 0 || strchr("xy",buf[0]) ) return;
- strcpy(let,buf);
- for( p++; *p && isspace(*p); p++ ) ;
- strncpy(buf,p,200);
- for( q=&buf[strlen(buf)-1]; q!=buf && isspace(*q); q-- ) *q = '\0';
- for( q=buf; *q; q++ ) if( *q == '!' ) *q = '+'; // translate oldstyle to newstyle
- if( !strcmp(buf,"+nil+") ) { // delete a macro
+ char key[256], value[256];
+ abc_extractkeyvalue(key, sizeof(key), value, sizeof(value), m);
+ if( strlen(key) > 1 || strchr("~HIJKLMNOPQRSTUVWXY",toupper(key[0])) == 0 ) return;
+ while( char *q = strchr(key, '!') )
+ *q = '+'; // translate oldstyle to newstyle
+ if( !strcmp(key,"+nil+") ) { // delete a macro
mp = NULL;
for( retval=h->umacro; retval; retval = retval->next ) {
- if( retval->name[0] == let[0] ) { // delete this one
+ if( retval->name[0] == key[0] ) { // delete this one
if( mp ) mp->next = retval->next;
else h->umacro = retval->next;
_mm_free(h->macrohandle, retval);
@@ -583,8 +601,8 @@
return;
}
retval = (ABCMACRO *)_mm_calloc(h->macrohandle, 1,sizeof(ABCTRACK));
- retval->name = DupStr(h->macrohandle, let,1);
- retval->subst = DupStr(h->macrohandle, buf, strlen(buf));
+ retval->name = DupStr(h->macrohandle, key, 1);
+ retval->subst = DupStr(h->macrohandle, value, strlen(value));
retval->n = 0;
retval->next = h->umacro; // by placing it up front we mask out the old macro until we +nil+ it
h->umacro = retval;
@@ -829,7 +847,7 @@
char vc[21];
int i, trans=0, voiceno=0, instrno = 1, channo = 0;
for( ; *voice == ' '; voice++ ) ; // skip leading spaces
- for( i=0; *voice && *voice != ']' && *voice != '%' && !isspace(*voice); voice++ ) // can work with inline voice instructions
+ for( i=0; i+1 < sizeof(vc) && *voice && *voice != ']' && *voice != '%' && !isspace(*voice); voice++ ) // can work with inline voice instructions
vc[i++] = *voice;
vc[i] = '\0';
prev = NULL;
@@ -992,11 +1010,15 @@
case cmdsync:
if( el ) {
el->next = ep->next;
+ if( !el->next )
+ tp->tail = el;
_mm_free(h->trackhandle,ep);
ep = el->next;
}
else {
tp->head = ep->next;
+ if( !tp->head )
+ tp->tail = NULL;
_mm_free(h->trackhandle,ep);
ep = tp->head;
}
@@ -1022,10 +1044,12 @@
_mm_free(h->trackhandle,tp);
tp = ptp;
}
- else {
+ else if (tp->next) {
h->track = tp->next;
_mm_free(h->trackhandle,tp);
tp = h->track;
+ } else {
+ break;
}
}
ptp = tp; // remember previous track
@@ -1492,7 +1516,7 @@
break;
}
d[chordbase] = d[chordnote];
- for( i=0; p[i] && p[i] != '"' && p[i] != '/' && p[i] != '(' && p[i] != ')' && p[i] != ' '; i++ ) s[i] = p[i];
+ for( i=0; i < sizeof(s) - 1 && p[i] && p[i] != '"' && p[i] != '/' && p[i] != '(' && p[i] != ')' && p[i] != ' '; i++ ) s[i] = p[i];
s[i] = '\0';
p = &p[i];
if( *p=='/' ) {
@@ -1625,7 +1649,7 @@
while( isspace(p[i]) )
i++;
while( p[i] == '+' ) {
- i += abc_getexpr(p+i+1, &term);
+ i += 1 + abc_getexpr(p+i+1, &term);
total += term;
while( isspace(p[i]) )
i++;
@@ -1750,6 +1774,8 @@
}
if( !nd ) tempo = 120;
else tempo = ns * nl * 4 / nd; // mod tempo is really BPM where one B is equal to a quartnote
+ if( tempo <= 0 )
+ tempo = 120;
if( invoice ) {
nl = global_tempo_factor;
nd = global_tempo_divider;
@@ -1814,6 +1840,8 @@
}
if( isdigit(p[i]) ) {
n=abc_getnumber(p+i,&k);
+ if( k == 0 )
+ k = 1;
if( p[i-1] == ')' )
j *= k; // never mind multiple parens, just take the worst case
else
@@ -1833,8 +1861,10 @@
for( k = n; k<j; k++ ) q[k-1] = q[k]; // shift to the left...
j--;
}
- else
+ else {
abc_message("Warning: Unbalanced right parens in P: definition %s",p);
+ break;
+ }
n = j - n + 1; // number of repeatable characters
i += abc_getnumber(p+i+1,&k);
while( k-- > 1 ) {
@@ -2099,7 +2129,7 @@
else
x++;
}
- if( fading && partno < 26 && i < 255 ) { // add single part with fading tracks
+ if( fading && partno < 25 && i < 254 ) { // add single part with fading tracks
partno++;
ptt[partno] = e->tracktick;
buf[i] = '\0'; // close up pfade with zero byte
@@ -2178,7 +2208,7 @@
break;
}
}
- if( buf[i] == '\n' ) i++;
+ if( i != bufsz-2 && buf[i] == '\n' ) i++;
buf[i] = '\0';
return buf;
}
@@ -2189,6 +2219,8 @@
int i;
int l = strlen(target);
int n = strlen(s);
+ if (l <= 0 ||n <= 0 || strstr(s, target))
+ return;
while( (p=strstr(h->line, target)) ) {
if( (i=strlen(h->line)) + n - l >= (int)h->len ) {
h->line = (char *)_mm_recalloc(h->allochandle, h->line, h->len<<1, sizeof(char));
@@ -2209,15 +2241,15 @@
static void abc_preprocess(ABCHANDLE *h, ABCMACRO *m)
{
int i, j, k, l, a, b;
- char t[32];
- char s[200],*p;
if( m->n ) {
k = m->n - m->name;
for( i=0; i<14; i++ ) {
- strncpy(t, m->name, 32);
+ char t[strlen(m->name) + 1];
+ strcpy(t, m->name);
t[k] = "CDEFGABcdefgab"[i];
l = strlen(m->subst);
- p = s;
+ char s[2 * l + 1];
+ char *p = s;
for( j=0; j<l; j++ ) {
a = m->subst[j];
if( a > 'g' && islower(a) ) {
@@ -2226,7 +2258,7 @@
*p++ = a;
if( i+b < 0 )
*p++ = ',';
- if( i+b > 13 )
+ else if( i+b > 13 )
*p++ = '\'';
}
else *p++ = a;
@@ -2837,7 +2869,7 @@
static int ABC_Key(const char *p)
{
int i,j;
- char c[8];
+ char c[8] = {0};
const char *q;
while( isspace(*p) ) p++;
i = 0;
@@ -4039,9 +4071,10 @@
abcstate = INBETWEEN;
break;
case INSKIPFORQUOTE:
- while( (ch=*p++) && (ch != '"') )
- ;
- if( !ch ) break;
+ while( *p && *p != '"' )
+ p++;
+ if( *p == '\0' )
+ break;
abcstate = INBODY;
// fall through
case INBODY:
@@ -4258,17 +4291,18 @@
if( h->tpr ) abc_add_drum_sync(h, h->tpr, h->tracktime); // don't start drumming from the beginning of time!
}
if( h->tpr && !h->drumon ) h->tpr = NULL;
- if( *p != '%' ) { // skip uninteresting lines
+ if( *p && *p != '%' ) { // skip uninteresting lines
// plough thru the songline gathering mos....
ch0 = ' ';
pp = 0;
while( (ch = *p++) ) {
- if( isalpha(ch) && *p != ':' ) { // maybe a macro
+ if( !pp && isalpha(ch) && *p != ':' ) { // maybe a macro
for( mp=h->umacro; mp; mp=mp->next ) {
if( ch == mp->name[0] ) {
pp = p;
p = mp->subst;
- ch = *p++;
+ ch = *p;
+ if( ch ) p++;
break;
}
}
@@ -4312,7 +4346,8 @@
if( !strncmp(p,"P:",2) ) { // a [P:X] field inline
if( abcparts != NULL ) {
// make h->tracktime start of a new age...
- abc_add_partbreak(h, h->track, h->tracktime);
+ if( h->track )
+ abc_add_partbreak(h, h->track, h->tracktime);
t = abc_patno(h, h->tracktime);
if( global_part == ' ' )
partpat[26][1] = t;
@@ -4335,7 +4370,8 @@
if( !strncmp(p,"Q:",2) ) {
abctempo = abc_extract_tempo(p+2,1);
for( ; *p && *p != ']'; p++ ) ;
- abc_add_tempo_event(h, h->track, h->tracktime, abctempo);
+ if( h->track )
+ abc_add_tempo_event(h, h->track, h->tracktime, abctempo);
break;
}
if( !strncmp(p,"I:",2) ) { // interpret some of the possibilitys
@@ -4367,7 +4403,7 @@
p += abc_notelen(p, ¬elen, ¬ediv);
if( *p == '-' ) {
p++;
- if( h->tp->tail->flg != 1 )
+ if( h->tp->tail && h->tp->tail->flg != 1 )
h->tp->tienote = h->tp->tail;
}
if( abcchord<8 ) {
@@ -4411,7 +4447,8 @@
if( thistime > abcticks(h->speed) ) thistime = abcticks(h->speed);
for( nl0=1; nl0<abcchord; nl0++ ) {
h->tp = abc_locate_track(h, h->tp->v, nl0+DRONEPOS2);
- h->tp->tail->tracktick = h->tracktime + thistime * nl0;
+ if( h->tp->tail )
+ h->tp->tail->tracktick = h->tracktime + thistime * nl0;
}
}
notelen *= cnotelen;
@@ -4443,7 +4480,7 @@
+ (thistime * cnl[abcchord] * cnotediv)/(cnd[abcchord] * cnotelen) );
}
else {
- if( ch=='-' && h->tp->tail->flg != 1 )
+ if( ch=='-' && h->tp->tail && h->tp->tail->flg != 1 )
h->tp->tienote = h->tp->tail; // copy noteon event to tienote in track
if( thistime > abcticks(h->speed) )
abc_add_noteoff(h, h->tp, h->tracktime - abcnoslurs);
@@ -4626,8 +4663,7 @@
if( !ch ) abcstate = INSKIPFORQUOTE;
break;
case '\\': // skip the rest of this line, should be the end of the line anyway
- while( (ch=*p++) )
- ;
+ while( *p ) p++;
ch = '\\'; // remember for invoice tempo changes....
break;
case '!': // line break, or deprecated old style decoration
@@ -4837,7 +4873,7 @@
p += abc_notelen(p, ¬elen, ¬ediv);
if( *p=='-' ) {
p++;
- if( h->tp->tail->flg != 1 )
+ if( h->tp->tail && h->tp->tail->flg != 1 )
h->tp->tienote = h->tp->tail;
}
tupletr = abc_tuplet(¬elen, ¬ediv, tupletp, tupletq, tupletr);
@@ -4951,7 +4987,7 @@
ABC_CleanupMacros(h); // we dont need them anymore
if( !h->track ) {
char buf[10];
- sprintf(buf,"%d",abcxnumber);
+ sprintf(buf,"%u",abcxnumber);
abc_message("abc X:%s has no body", buf);
h->track = abc_check_track(h, h->track); // for sanity...
}
@@ -5045,14 +5081,19 @@
#else
m_nType = MOD_TYPE_ABC;
numpat = 1+(modticks(h->tracktime) / h->speed / 64);
+ if( numpat > MAX_PATTERNS )
+ numpat = MAX_PATTERNS;
m_nDefaultSpeed = h->speed;
m_nChannels = abc_numtracks(h);
m_dwSongFlags = SONG_LINEARSLIDES;
m_nMinPeriod = 28 << 2;
m_nMaxPeriod = 1712 << 3;
// orderlist
- for(t=0; t < (uint32_t)orderlen; t++)
+ for(t=0; t < (uint32_t)orderlen; t++){
+ if( t >= MAX_ORDERS )
+ break;
Order[t] = orderlist[t];
+ }
free(orderlist); // get rid of orderlist memory
#endif
#ifdef NEWMIKMOD
@@ -5095,6 +5136,8 @@
}
// ============================================================
// set panning positions
+ if( m_nChannels > MAX_BASECHANNELS )
+ m_nChannels = MAX_BASECHANNELS;
for(t=0; t<m_nChannels; t++) {
ChnSettings[t].nPan = 0x30+((t+2)%5)*((0xD0 - 0x30)/5); // 0x30 = std s3m val
ChnSettings[t].nVolume = 64;