# HG changeset patch # User chainsaw # Date 1152372558 25200 # Node ID c71e2ef2dcf47679dd4e780affa8bb1de72b343e # Parent d2c411305bf8ea0a6ecaa60be520746a5f72d1de [svn] Security fixes from AdPlug CVS (their July 7 commit shortly before the secunia announcement). diff -r d2c411305bf8 -r c71e2ef2dcf4 ChangeLog --- a/ChangeLog Fri Jul 07 12:42:32 2006 -0700 +++ b/ChangeLog Sat Jul 08 08:29:18 2006 -0700 @@ -1,3 +1,11 @@ +2006-07-07 19:42:32 +0000 Tony Vroon + revision [1664] + Modplug conftest fix by Christian "Joker" Birchinger from Gentoo. + + Changes: Modified: + +1 -1 trunk/configure.ac + + 2006-07-07 15:37:38 +0000 Yoshiki Yazawa revision [1662] - libguess/Makefile is not necessary. diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/cff.cpp --- a/Plugins/Input/adplug/core/cff.cpp Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/cff.cpp Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* AdPlug - Replayer for many OPL2/OPL3 audio file formats. - Copyright (C) 1999 - 2002 Simon Peter , et al. + Copyright (C) 1999 - 2006 Simon Peter , et al. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -328,7 +328,8 @@ memset(dictionary,0,0x8000); cleanup(); - startup(); + if(!startup()) + goto out; // LZW while (1) @@ -343,7 +344,8 @@ if (new_code == 1) { cleanup(); - startup(); + if(!startup()) + goto out; continue; } @@ -369,12 +371,18 @@ unsigned long repeat_counter = get_code(); + if(output_length + repeat_counter * repeat_length > 0x10000) { + output_length = 0; + goto out; + } + for (unsigned int i=0;i 0x10000) { + output_length = 0; + goto out; + } + for (int i=0;i 0x10000) { + output_length = 0; + return 0; + } + for (int i=0;i, et al. + Copyright (C) 1999 - 2006 Simon Peter , et al. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -51,7 +51,7 @@ void translate_code(unsigned long code, unsigned char *string); void cleanup(); - void startup(); + int startup(); void expand_dictionary(unsigned char *string); diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/dmo.cpp --- a/Plugins/Input/adplug/core/dmo.cpp Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/dmo.cpp Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* Adplug - Replayer for many OPL2/OPL3 audio file formats. - Copyright (C) 1999 - 2004 Simon Peter, , et al. + Copyright (C) 1999 - 2004, 2006 Simon Peter, , et al. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -55,12 +55,12 @@ binistream *f; // check header + dmo_unpacker *unpacker = new dmo_unpacker; + unsigned char chkhdr[16]; + if(!fp.extension(filename, ".dmo")) return false; f = fp.open(filename); if(!f) return false; - dmo_unpacker *unpacker = new dmo_unpacker; - unsigned char chkhdr[16]; - f->readString((char *)chkhdr, 16); if (!unpacker->decrypt(chkhdr, 16)) @@ -87,7 +87,7 @@ unsigned char *module = new unsigned char [unpacked_length]; // unpack - if (!unpacker->unpack(packed_module+12,module)) + if (!unpacker->unpack(packed_module+12,module,unpacked_length)) { delete unpacker; delete [] packed_module; @@ -296,6 +296,9 @@ { cx = (code & 0x3F) + 1; + if(opos + cx >= oend) + return -1; + for (int i=0;i> 5) + 1; cx = (par1 & 0x1F) + 3; - for(int i=0;i= oend) + return -1; + + for(int i=0;i> 4) + 3; bx = par1 & 0x0F; - for(i=0;i= oend) + return -1; + + for(i=0;i> 4) + 4; ax = par2 & 0x0F; - for(i=0;i= oend) + return -1; + + for(i=0;i, et al. + Copyright (C) 1999 - 2006 Simon Peter, , et al. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -38,11 +38,14 @@ class dmo_unpacker { public: bool decrypt(unsigned char *buf, long len); - long unpack(unsigned char *ibuf, unsigned char *obuf); + long unpack(unsigned char *ibuf, unsigned char *obuf, + unsigned long outputsize); private: unsigned short brand(unsigned short range); short unpack_block(unsigned char *ibuf, long ilen, unsigned char *obuf); + unsigned long bseed; + unsigned char *oend; }; }; diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/dtm.cpp --- a/Plugins/Input/adplug/core/dtm.cpp Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/dtm.cpp Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* Adplug - Replayer for many OPL2/OPL3 audio file formats. - Copyright (C) 1999 - 2003 Simon Peter, , et al. + Copyright (C) 1999 - 2006 Simon Peter, , et al. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -61,6 +61,11 @@ // get line length unsigned char bufstr_length = f->readInt(1); + if(bufstr_length > 80) { + fp.close(f); + return false; + } + // read line if (bufstr_length) { diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/dtm.h --- a/Plugins/Input/adplug/core/dtm.h Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/dtm.h Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* Adplug - Replayer for many OPL2/OPL3 audio file formats. - Copyright (C) 1999 - 2003 Simon Peter, , et al. + Copyright (C) 1999 - 2006 Simon Peter, , et al. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/fmopl.c --- a/Plugins/Input/adplug/core/fmopl.c Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/fmopl.c Sat Jul 08 08:29:18 2006 -0700 @@ -755,7 +755,7 @@ { OPL_CH *CH; int slot; - size_t block_fnum; + int block_fnum; switch(r&0xe0) { @@ -1343,10 +1343,8 @@ { if(OPL->keyboardhandler_r) return OPL->keyboardhandler_r(OPL->keyboard_param); - else { + else LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n")); - return 0; /* Avoid warning about empty else clause */ - } } return 0; #if 0 @@ -1358,10 +1356,8 @@ { if(OPL->porthandler_r) return OPL->porthandler_r(OPL->port_param); - else { + else LOG(LOG_WAR,("OPL:read unmapped I/O port\n")); - return 0; /* Avoid warning about empty else clause */ - } } return 0; case 0x1a: /* PCM-DATA */ diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/fprovide.h --- a/Plugins/Input/adplug/core/fprovide.h Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/fprovide.h Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* * Adplug - Replayer for many OPL2/OPL3 audio file formats. - * Copyright (C) 1999 - 2002 Simon Peter, , et al. + * Copyright (C) 1999 - 2006 Simon Peter, , et al. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,10 @@ class CFileProvider { public: - virtual ~CFileProvider() { } + virtual ~CFileProvider() + { + } + virtual binistream *open(std::string) const = 0; virtual void close(binistream *) const = 0; @@ -40,7 +43,6 @@ class CProvider_Filesystem: public CFileProvider { public: - virtual ~CProvider_Filesystem() { } virtual binistream *open(std::string filename) const; virtual void close(binistream *f) const; }; diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/mtk.cpp --- a/Plugins/Input/adplug/core/mtk.cpp Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/mtk.cpp Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* * Adplug - Replayer for many OPL2/OPL3 audio file formats. - * Copyright (C) 1999 - 2003 Simon Peter, , et al. + * Copyright (C) 1999 - 2006 Simon Peter, , et al. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -68,6 +68,9 @@ ctrlmask = 0x8000; } if(!(ctrlbits & ctrlmask)) { // uncompressed data + if(orgptr >= header.size) + goto err; + org[orgptr] = cmp[cmpptr]; orgptr++; cmpptr++; continue; @@ -78,11 +81,34 @@ cnt = cmp[cmpptr] & 0x0f; cmpptr++; switch(cmd) { - case 0: cnt += 3; memset(&org[orgptr],cmp[cmpptr],cnt); cmpptr++; orgptr += cnt; break; - case 1: cnt += (cmp[cmpptr] << 4) + 19; memset(&org[orgptr],cmp[++cmpptr],cnt); cmpptr++; orgptr += cnt; break; - case 2: offs = (cnt+3) + (cmp[cmpptr] << 4); cnt = cmp[++cmpptr] + 16; cmpptr++; - memcpy(&org[orgptr],&org[orgptr - offs],cnt); orgptr += cnt; break; - default: offs = (cnt+3) + (cmp[cmpptr++] << 4); memcpy(&org[orgptr],&org[orgptr-offs],cmd); orgptr += cmd; break; + case 0: + if(orgptr + cnt > header.size) goto err; + cnt += 3; + memset(&org[orgptr],cmp[cmpptr],cnt); + cmpptr++; orgptr += cnt; + break; + + case 1: + if(orgptr + cnt > header.size) goto err; + cnt += (cmp[cmpptr] << 4) + 19; + memset(&org[orgptr],cmp[++cmpptr],cnt); + cmpptr++; orgptr += cnt; + break; + + case 2: + if(orgptr + cnt > header.size) goto err; + offs = (cnt+3) + (cmp[cmpptr] << 4); + cnt = cmp[++cmpptr] + 16; cmpptr++; + memcpy(&org[orgptr],&org[orgptr - offs],cnt); + orgptr += cnt; + break; + + default: + if(orgptr + cmd > header.size) goto err; + offs = (cnt+3) + (cmp[cmpptr++] << 4); + memcpy(&org[orgptr],&org[orgptr-offs],cmd); + orgptr += cmd; + break; } } delete [] cmp; @@ -106,4 +132,9 @@ delete [] org; rewind(0); return true; + + err: + delete [] cmp; + delete [] org; + return false; } diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/mtk.h --- a/Plugins/Input/adplug/core/mtk.h Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/mtk.h Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* * Adplug - Replayer for many OPL2/OPL3 audio file formats. - * Copyright (C) 1999 - 2003 Simon Peter, , et al. + * Copyright (C) 1999 - 2006 Simon Peter, , et al. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,7 +23,7 @@ class CmtkLoader: public ChscPlayer { -public: + public: static CPlayer *factory(Copl *newopl); CmtkLoader(Copl *newopl) @@ -45,6 +45,6 @@ std::string getinstrument(unsigned int n) { return std::string(instname[n]); }; -private: + private: char title[34],composer[34],instname[0x80][34]; }; diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/opl.h --- a/Plugins/Input/adplug/core/opl.h Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/opl.h Sat Jul 08 08:29:18 2006 -0700 @@ -1,6 +1,6 @@ /* * Adplug - Replayer for many OPL2/OPL3 audio file formats. - * Copyright (C) 1999 - 2005 Simon Peter, , et al. + * Copyright (C) 1999 - 2006 Simon Peter, , et al. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,7 +25,6 @@ class Copl { public: - virtual ~Copl() { } typedef enum { TYPE_OPL2, TYPE_OPL3, TYPE_DUAL_OPL2 } ChipType; @@ -35,6 +34,10 @@ { } + virtual ~Copl() + { + } + virtual void write(int reg, int val) = 0; // combined register select + data write virtual void setchip(int n) // select OPL chip { diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/rix.cpp --- a/Plugins/Input/adplug/core/rix.cpp Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/rix.cpp Sat Jul 08 08:29:18 2006 -0700 @@ -53,14 +53,14 @@ } CrixPlayer::CrixPlayer(Copl *newopl) - : CPlayer(newopl), buf_addr(0) + : CPlayer(newopl), flag_mkf(0), file_buffer(0), buf_addr(0) { } CrixPlayer::~CrixPlayer() { - if(buf_addr) - delete [] buf_addr; + if(file_buffer) + delete [] file_buffer; } bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp) @@ -68,25 +68,28 @@ binistream *f = fp.open(filename); if(!f) return false; unsigned long i=0; - if(f->readInt(2)!=0x55aa) { fp.close(f);return false; } - buf_addr = new unsigned char [fp.filesize(f) + 1]; - buf_addr[i++]=0xaa;buf_addr[i++]=0x55; + if(stricmp(filename.substr(filename.length()-4,4).c_str(),".mkf")==0) + { + flag_mkf=1; + f->seek(0); + int offset=f->readInt(4); + f->seek(offset); + } + if(f->readInt(4)!=0x55aa){ fp.close(f);return false; } + file_buffer = new unsigned char [fp.filesize(f) + 1]; + f->seek(0); while(!f->eof()) - buf_addr[i++]=f->readInt(1); + file_buffer[i++]=f->readInt(1); length=i; fp.close(f); - + if(!flag_mkf) + buf_addr=file_buffer; rewind(0); return true; } bool CrixPlayer::update() { - if (delay>100) { - delay-=100; - return true; - } else delay=1; - int_08h_entry(); return !dro_end; } @@ -104,7 +107,6 @@ band_low = 0; e0_reg_flag = 0; bd_modify = 0; - delay = 1; sustain = 0; dro_end = 0; pos = index = 0; @@ -119,16 +121,37 @@ memset(displace, 0, 11 * sizeof(unsigned short)); memset(reg_bufs, 0, 18 * sizeof(ADDT)); + if(flag_mkf) + { + unsigned int *buf_index=(unsigned int *)file_buffer; + int offset1=buf_index[subsong],offset2; + while((offset2=buf_index[++subsong])==offset1); + length=offset2-offset1+1; + buf_addr=file_buffer+offset1; + } opl->init(); opl->write(1,32); // go to OPL2 mode set_new_int(); data_initial(); } +unsigned int CrixPlayer::getsubsongs() +{ + if(flag_mkf) + { + unsigned int *buf_index=(unsigned int *)file_buffer; + int songs=buf_index[0]/4,i=0; + for(i=0;i 100) return 1000 / 100; - else return 1000.0 / (double)delay; + return 70.0f; } /*------------------Implemention----------------------------*/ @@ -239,7 +262,6 @@ mutex++; band_sus = rix_proc(); if(band_sus) sustain += band_sus; - delay=sustain; mutex--; if(band_sus == 0) { @@ -249,7 +271,7 @@ } else { - if(band_sus) sustain -= 9; /* aging */ + if(band_sus) sustain -= 14; /* aging */ break; } } diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/rix.h --- a/Plugins/Input/adplug/core/rix.h Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/rix.h Sat Jul 08 08:29:18 2006 -0700 @@ -34,6 +34,7 @@ bool update(); void rewind(int subsong); float getrefresh(); + unsigned int getsubsongs(); std::string gettype() { return std::string("Softstar RIX OPL Music Format"); }; @@ -43,7 +44,28 @@ unsigned char v[14]; } ADDT; - unsigned char dro[128000]; + int flag_mkf; + unsigned char *file_buffer; + unsigned char *buf_addr; /* rix files' buffer */ + unsigned short buffer[300]; + unsigned short a0b0_data2[11]; + unsigned char a0b0_data3[18]; + unsigned char a0b0_data4[18]; + unsigned char a0b0_data5[96]; + unsigned char addrs_head[96]; + unsigned short insbuf[28]; + unsigned short displace[11]; + ADDT reg_bufs[18]; + unsigned long pos,length; + unsigned char index; + + static const unsigned char adflag[18]; + static const unsigned char reg_data[18]; + static const unsigned char ad_C0_offs[18]; + static const unsigned char modify[28]; + static const unsigned char bd_reg_data[124]; + static unsigned char for40reg[18]; + static unsigned short mus_time; unsigned int I,T; unsigned short mus_block; unsigned short ins_block; @@ -57,27 +79,6 @@ unsigned char bd_modify; int sustain; int dro_end; - unsigned char *buf_addr; /* rix files' buffer */ - unsigned short buffer[300]; - unsigned short a0b0_data2[11]; - unsigned char a0b0_data3[18]; - unsigned char a0b0_data4[18]; - unsigned char a0b0_data5[96]; - unsigned char addrs_head[96]; - unsigned short insbuf[28]; - unsigned short displace[11]; - ADDT reg_bufs[18]; - unsigned long pos,length; - unsigned char index; - unsigned short delay; - - static const unsigned char adflag[18]; - static const unsigned char reg_data[18]; - static const unsigned char ad_C0_offs[18]; - static const unsigned char modify[28]; - static const unsigned char bd_reg_data[124]; - static unsigned char for40reg[18]; - static unsigned short mus_time; #define ad_08_reg() ad_bop(8,0) /**/ inline void ad_20_reg(unsigned short); /**/ diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/s3m.cpp --- a/Plugins/Input/adplug/core/s3m.cpp Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/s3m.cpp Sat Jul 08 08:29:18 2006 -0700 @@ -68,7 +68,8 @@ // file validation section checkhead = new s3mheader; load_header(f, checkhead); - if((checkhead->kennung != 0x1a) || (checkhead->typ != 16)) { + if(checkhead->kennung != 0x1a || checkhead->typ != 16 + || checkhead->insnum > 99) { delete checkhead; fp.close(f); return false; } else if(strncmp(checkhead->scrm,"SCRM",4)) { @@ -91,6 +92,13 @@ // load section f->seek(0); // rewind for load load_header(f, &header); // read header + + // security check + if(header.ordnum > 256 || header.insnum > 99 || header.patnum > 99) { + fp.close(f); + return false; + } + for(i = 0; i < header.ordnum; i++) orders[i] = f->readInt(1); // read orders for(i = 0; i < header.insnum; i++) insptr[i] = f->readInt(2); // instrument parapointers for(i = 0; i < header.patnum; i++) pattptr[i] = f->readInt(2); // pattern parapointers @@ -363,7 +371,7 @@ } if(!del) - del = speed - 1;// speed compensation + del = speed - 1; // speed compensation if(!pattbreak) { // next row (only if no manual advance) crow++; if(crow > 63) { diff -r d2c411305bf8 -r c71e2ef2dcf4 Plugins/Input/adplug/core/u6m.cpp --- a/Plugins/Input/adplug/core/u6m.cpp Fri Jul 07 12:42:32 2006 -0700 +++ b/Plugins/Input/adplug/core/u6m.cpp Sat Jul 08 08:29:18 2006 -0700 @@ -22,6 +22,13 @@ #include "u6m.h" +// Makes security checks on output buffer before writing +#define SAVE_OUTPUT_ROOT(c, d, p) \ +if(p < d.size) \ + output_root(c, d.data, p); \ +else \ + return false; + CPlayer *Cu6mPlayer::factory(Copl *newopl) { return new Cu6mPlayer(newopl); @@ -208,7 +215,7 @@ long bytes_written = 0; int cW; - int pW = 0; + int pW; unsigned char C; while (!end_marker_reached) @@ -223,7 +230,7 @@ dictionary_size = 0x200; dictionary.reset(); cW = get_next_codeword(bits_read, source.data, codeword_size); - output_root((unsigned char)cW, dest.data, bytes_written); + SAVE_OUTPUT_ROOT((unsigned char)cW, dest, bytes_written); break; // end of compressed file has been reached case 0x101: @@ -239,7 +246,7 @@ // output the string represented by cW while (!root_stack.empty()) { - output_root(root_stack.top(), dest.data, bytes_written); + SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written); root_stack.pop(); } // add pW+C to the dictionary @@ -263,17 +270,17 @@ // output the string represented by pW while (!root_stack.empty()) { - output_root(root_stack.top(), dest.data, bytes_written); + SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written); root_stack.pop(); } // output the char C - output_root(C, dest.data, bytes_written); + SAVE_OUTPUT_ROOT(C, dest, bytes_written); // the new dictionary entry must correspond to cW // if it doesn't, something is wrong with the lzw-compressed data. if (cW != next_free_codeword) { -/* printf("cW != next_free_codeword!\n"); + /* printf("cW != next_free_codeword!\n"); exit(-1); */ return false; }