Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#8 security issues in libmodplug

closed-fixed
Konstanty
None
5
2009-04-07
2006-10-03
vorlon078
No

advisory can be found at
<http://aluigi.altervista.org/adv/mptho-adv.txt>

quoting:

=======
2) Bugs
=======

---------------------------------------------------
A] various global buffer overflows in ReadITProject
---------------------------------------------------

All the text fields in the ITP files are not sanitized
so is possible
to overflow the global variables through this function
and possibly
executing malicious code (confirmed in my tests).
Note: ITP files are not supported in libmodplug

From soundlib/Load_it.cpp:

BOOL CSoundFile::ReadITProject(LPCBYTE lpStream, DWORD
dwMemLength)
{
...
// Song name

// name string length
memcpy(&id,lpStream+streamPos,sizeof(DWORD));
len = id;
streamPos += sizeof(DWORD);

// name string
memcpy(&m_szNames[0],lpStream+streamPos,len);
streamPos += len;
...
(other overflows)
...

------------------------------
B] heap overflow in ReadSample
------------------------------

In some modules the ReadSample function can be used to
cause a heap
overflow through an invalid nLength value.
As visible by the code below, nLength is incremented of
6 bytes (mem)
and in some cases its value is multiplicated by two,
the final value is
then used to allocate pIns->pSample (FYI AllocateSample
allocates
"(nbytes + 39) & ~7" and returns the pointer plus 16).
An attacker, after having forced the program to
allocate 0 bytes, will
be able to overflow the memory through the memcpy
instructions which
will copy (depending by nFlags) all the remaining bytes
in the file.
The best type of module for exploiting this
vulnerability seems to be
AMF.

From soundlib/Sndfile.cpp:

UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT
nFlags, LPCSTR lpMemFile, DWORD dwMemLength)
//------------------------------------------------------------------------------------------------
{
UINT len = 0, mem = pIns->nLength+6;

if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile))
return 0;
if (pIns->nLength > MAX_SAMPLE_LENGTH)
pIns->nLength = MAX_SAMPLE_LENGTH;
...
if ((pIns->pSample = AllocateSample(mem)) == NULL)
...
default:
len = pIns->nLength;
if (len > dwMemLength) len = pIns->nLength =
dwMemLength;
memcpy(pIns->pSample, lpMemFile, len);
}
...

Discussion

  • Logged In: NO

    Fixed in CVS.

     
  • Konstanty
    Konstanty
    2009-04-07

    • assigned_to: nobody --> metaplasma
    • status: open --> closed-fixed
     
  • Konstanty
    Konstanty
    2009-04-07

    Fixed in: 0.8.4 (previous release)