Reject ATRAC files with oversized packets at parse time; honor Verify errors

- InitContextFromTrackInfo now rejects files where sampleSize (from
  blockAlign) exceeds the buffer size, instead of only clamping later in
  DecodeForSas. Keep the DecodeForSas check as defense-in-depth since a
  large buffer could still allow a crafted packet to overflow the fixed
  assembly buffer.
- CChunkFileReader::Verify now returns ERROR_BROKEN_STATE if bounds
  checking fails, so modified savestates are rejected here too.
This commit is contained in:
Henrik Rydgård committed 2026-08-01 11:57:27 +02:00
1 parent 398a678b88
commit 2100e4ec47
2 files changed
+12 -1

No files matched your search

+3
View File
@@ -340,6 +340,9 @@ public:
p.SetMode(PointerWrap::MODE_VERIFY);
_class.DoState(p);
if (p.error == PointerWrap::ERROR_FAILURE) {
return ERROR_BROKEN_STATE;
}
return ERROR_NONE;
}
+9 -1
View File
@@ -217,6 +217,11 @@ int InitContextFromTrackInfo(SceAtracContext *ctx, const TrackInfo *wave, u32 bu
(ctx->info).curBuffer = 0;
(ctx->info).bufferByte = bufferSize;
(ctx->info).streamOff = dataOff;
// A packet larger than the buffer can't be streamed or assembled into the
// SAS assembly buffer. Reject it early, as sampleSize is file-derived.
if ((ctx->info).sampleSize > (u32)bufferSize) {
return SCE_ERROR_ATRAC_BAD_CODEC_PARAMS;
}
if ((ctx->info).loopEnd > endSample) {
return SCE_ERROR_ATRAC_BAD_CODEC_PARAMS;
}
@@ -1219,7 +1224,10 @@ void Atrac2::DecodeForSas(s16 *dstData, int *bytesWritten, int *finish) {
DEBUG_LOG(Log::Atrac, "Streaming atrac through sas, and hit the end of buffer %d", sas_.curBuffer);
// The packet spans two buffers and is reassembled into the fixed
// assembly buffer. Bail out if it can't possibly fit there.
// assembly buffer below. InitContextFromTrackInfo already rejects
// sampleSize > bufferByte, but a crafted file can still pass that with
// a large buffer, so also guard against sampleSize exceeding the fixed
// assembly buffer here.
if ((u32)info.sampleSize > sizeof(assembly)) {
ERROR_LOG(Log::Atrac, "SAS packet too large for assembly buffer: %d", info.sampleSize);
*bytesWritten = 0;