Skip to content

Commit 019e926

Browse files
AliceLRsezero
authored andcommitted
Fix PSM loader crash bugs found by libFuzzer.
* PSM: fix out-of-bounds reads due to dereferencing lpStream before any bounds checks. * PSM: fix out-of-bounds reads due to reading pPsmPat.data from the stack instead of the input buffer. * PSM: fix out-of-bounds reads due to invalid samples in patterns. * PSM: fix missing pattern length byte-swapping. * PSM: constify pattern data pointer derived from lpStream. Konstanty#58
1 parent 6efafba commit 019e926

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

src/load_psm.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static void swap_PSMSAMPLE(PSMSAMPLE* p){
9898
BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
9999
//-----------------------------------------------------------
100100
{
101-
PSMCHUNK pfh = *(const PSMCHUNK *)lpStream;
101+
PSMCHUNK pfh;
102102
DWORD dwMemPos, dwSongPos;
103103
// DWORD smpnames[MAX_SAMPLES];
104104
DWORD patptrs[MAX_PATTERNS];
@@ -108,6 +108,7 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
108108
if (dwMemLength < 256) return FALSE;
109109

110110
// Swap chunk
111+
pfh = *(const PSMCHUNK *)lpStream;
111112
swap_PSMCHUNK(&pfh);
112113

113114
// Chunk0: "PSM ",filesize,"FILE"
@@ -279,14 +280,17 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
279280
{
280281
PSMPATTERN pPsmPat = *(const PSMPATTERN *)(lpStream+patptrs[nPat]+8);
281282
swap_PSMPATTERN(&pPsmPat);
282-
ULONG len = *(DWORD *)(lpStream+patptrs[nPat]+4) - 12;
283+
PSMCHUNK pchunk = *(const PSMCHUNK *)(lpStream+patptrs[nPat]);
284+
swap_PSMCHUNK(&pchunk);
285+
286+
ULONG len = pchunk.len - 12;
283287
UINT nRows = pPsmPat.rows;
284288
if (len > pPsmPat.size) len = pPsmPat.size;
285289
if ((nRows < 64) || (nRows > 256)) nRows = 64;
286290
PatternSize[nPat] = nRows;
287291
if ((Patterns[nPat] = AllocatePattern(nRows, m_nChannels)) == NULL) break;
288292
MODCOMMAND *m = Patterns[nPat];
289-
BYTE *p = pPsmPat.data;
293+
const BYTE *p = lpStream + patptrs[nPat] + 20;
290294
MODCOMMAND *sp, dummy;
291295
UINT pos = 0;
292296
UINT row = 0;
@@ -331,7 +335,8 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
331335
//if (!nPat) Log("note+ins: %02X.%02X\n", note, nins);
332336
if ((!nPat) && (nins >= m_nSamples)) Log("WARNING: invalid instrument number (%d)\n", nins);
333337
#endif
334-
sp->instr = samplemap[nins];
338+
if (nins < MAX_SAMPLES)
339+
sp->instr = samplemap[nins];
335340
}
336341
// Volume
337342
if ((flags & 0x20) && (pos < len))

0 commit comments

Comments
 (0)