Package: libmodplug Version: 1:0.8.8.2-3 Severity: normal Tags: patch User: ubuntu-de...@lists.ubuntu.com 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;