sceSasSetGrain/SasReverb: validate grain size and reverb preset index

sceSasSetGrain took no validation at all, unlike sceSasInit's grain
size check - a bad value could both throw on SasInstance::SetGrainSize's
allocation and, for a moderately large but successfully-allocated
value beyond PSP_SAS_MAX_GRAIN, read out of bounds of the fixed-size
mixTemp_ buffer during mixing. Apply the same bounds sceSasInit uses.

SasReverb::SetPreset() only checked the upper bound of `preset` before
indexing presets[], not the lower bound (-1 means "off"). The only
live HLE entry point (sceSasRevType) already clamps to [-1, 8], but
DoState() passes a savestate-deserialized value straight through with
no revalidation, so a corrupted/malicious savestate could index
presets[] negatively.
This commit is contained in:
Henrik Rydgård committed 2026-08-12 09:43:23 +02:00
1 parent bfbe44ad1c
commit 90d8be9348
2 files changed
+13 -1

No files matched your search

+8
View File
@@ -637,6 +637,14 @@ static u32 sceSasGetGrain(u32 core) {
}
static u32 sceSasSetGrain(u32 core, int grain) {
// Unlike sceSasInit, this took no validation at all - a bad grain size could
// both throw on the allocation below and (for a moderately large but successfully
// allocated value beyond PSP_SAS_MAX_GRAIN) read out of bounds of the fixed-size
// mixTemp_ buffer during mixing. Apply the same bounds sceSasInit uses.
if (grain < 0x40 || grain > 0x800 || (grain & 0x1F) != 0) {
ERROR_LOG_REPORT(Log::sceSas, "sceSasSetGrain(%08x, %i): bad grain size", core, grain);
return hleNoLog(SCE_SAS_ERROR_INVALID_GRAIN);
}
__SasDrain();
sas->SetGrainSize(grain);
return hleLogInfo(Log::sceSas, 0);
+5 -1
View File
@@ -169,7 +169,11 @@ const char *SasReverb::GetPresetName(int preset) {
}
void SasReverb::SetPreset(int preset) {
if (preset < (int)ARRAY_SIZE(presets))
// -1 means "off"; anything else must be a valid index into presets[]. Only the
// upper bound was checked before, so a value below -1 (e.g. from a corrupted
// savestate - the sceSasRevType HLE call itself already clamps to [-1, 8]) would
// index presets[] negatively below.
if (preset >= -1 && preset < (int)ARRAY_SIZE(presets))
preset_ = preset;
if (preset_ != -1) {
pos_ = BUFSIZE - presets[preset_].size;