raw_bytes_per_frame (the 'fmt ' chunk's blockAlign field) is
unvalidated file data, and was used unchecked in three places:
- Divided into the 'data' chunk size to compute numFrames - a value
of 0 divides by zero (crash).
- malloc()'d for raw_data was never null-checked before ReadData()
wrote into it.
- Passed directly as the read length to the audio decoder on every
frame, regardless of how much data is actually left in raw_data at
the current offset - a bogus blockAlign larger than the real 'data'
chunk size reads past the (padded) allocation into the decoder.
Clamp it to what's actually available.
IsSimpleWAV() only checked raw_bytes_per_frame's upper bound, not that
it exactly matched one of the two cases Sample::Load() actually
handles (16-bit or 8-bit raw PCM) - a value in between passed the
check but matched neither of Load()'s conversion branches, leaving its
output buffer uninitialized and played back as heap garbage.
Reachable via a WAV/AT3 file parsed by BackgroundAudio.cpp - either
the menu background music preview (any EBOOT.PBP's SND0.AT3 track,
just from browsing the game list) or a user-configurable achievement
sound file.
RIFFReader::ReadData() trusted its count argument completely and
memcpy'd straight from the internal buffer with no bounds check.
Hardened it to clamp against the buffer and zero-fill any shortfall,
as defense in depth.
The actual reachable bug was in BackgroundAudio.cpp: it read a WAV
'smpl' chunk into a vector sized by GetCurrentChunkSize(), then
unconditionally indexed smplData[28] (and, for the loop array,
smplData[36]) with no check that the chunk was actually that large -
a short/corrupt chunk in a game's background-music WAV caused a heap
OOB read. Also fixes &smplData[0] being UB when the chunk is empty.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4QAoxV2KY7ek4PcZw3WvY
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix
* Move the resampler usage to a common file, AudioCommon.
Ports that don't want to use the resampler can now simply exclude that
file and provide their own implementation. Next up, libretro will be
converted to do it that way.
* Android.mk typo
* libretro makefile fix
* libretro buildfix
* libretro: try a different approach for the temporary solution
* duh
* double duh
It might be possible a clock is adjusting backwards slightly after a time
update, and this could've caused sz to become negative.
Based on crash reports.
* Move and rename file_util/fd_util to Common/File/FileUtil and DirListing
Let's also move net while we're at it.
Move the ZIM/PNG loaders over to Common.
Move the UI framework into Common
iOS buildfix
* Buildfix
* Buildfixes
* Apple buildfix
* This typo again..
* UWP buildfix
* Fix build of PPSSPPQt, such as it is (it's not in good condition...)
* Guess what? Another buildfix.
Buildfixing
Move some file util files
Buildfix
Move KeyMap.cpp/h to Core where they belong better.
libretro buildfix attempt
Move ini_file
More buildfixes