mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 01:29:41 +01:00
Fix heap overflow via unsigned underflow in legacy Atrac::EnqueueForSas
The space-left clamp was computed in unsigned 32-bit arithmetic, so a crafted fileoffset/FirstOffsetExtra could underflow to a huge value and leave addbytes unclamped, driving a Memory::Memcpy past dataBuf_. Compute the clamp in signed 64-bit, clamp negatives to 0, and skip the copy when there's nothing to write.
This commit is contained in:
1 parent
725cd691b3
commit
942a76cfaa
1 file changed
+12
-3
+12
-3
@@ -960,15 +960,24 @@ void Atrac::CheckForSas() {
|
||||
}
|
||||
|
||||
int Atrac::EnqueueForSas(u32 bufPtr, u32 bytesToAdd) {
|
||||
int addbytes = std::min(bytesToAdd, track_.fileSize - first_.fileoffset - track_.FirstOffsetExtra());
|
||||
Memory::Memcpy(dataBuf_ + first_.fileoffset + track_.FirstOffsetExtra(), bufPtr, addbytes, "AtracAddStreamData");
|
||||
// Compute in signed 64-bit so an attacker-controlled fileoffset /
|
||||
// FirstOffsetExtra can't underflow the space-left clamp and leave
|
||||
// addbytes unclamped.
|
||||
const s64 destOffset = (s64)first_.fileoffset + track_.FirstOffsetExtra();
|
||||
const s64 spaceLeft = (s64)track_.fileSize - destOffset;
|
||||
s64 addbytes = std::min<s64>((s64)bytesToAdd, spaceLeft);
|
||||
if (addbytes < 0)
|
||||
addbytes = 0;
|
||||
if (addbytes > 0) {
|
||||
Memory::Memcpy(dataBuf_ + destOffset, bufPtr, (size_t)addbytes, "AtracAddStreamData");
|
||||
}
|
||||
first_.size += bytesToAdd;
|
||||
if (first_.size >= track_.fileSize) {
|
||||
first_.size = track_.fileSize;
|
||||
if (bufferState_ == ATRAC_STATUS_HALFWAY_BUFFER)
|
||||
bufferState_ = ATRAC_STATUS_ALL_DATA_LOADED;
|
||||
}
|
||||
first_.fileoffset += addbytes;
|
||||
first_.fileoffset += (u32)addbytes;
|
||||
// refresh context_
|
||||
WriteContextToPSPMem();
|
||||
return 0;
|
||||
|
||||
Reference in new issue
Block a user