Fix Shorten AIFF chunk offset wrap (#1381)

A crafted embedded AIFF chunk size could wrap the parser offset and
make it repeatedly process the same chunk, causing a denial of service.

Validate AIFF chunk headers and padded sizes against the remaining
verbatim-header data, and advance every parsed chunk to its checked end.
This commit is contained in:
Acts1631
2026-08-01 06:12:47 +02:00
committed by GitHub
parent 54ae7d8ac4
commit 3aa04e3be4
+17 -4
View File
@@ -471,14 +471,27 @@ void Shorten::File::read(AudioProperties::ReadStyle propertiesStyle)
auto sawCommonChunk = false;
while(offset < chunkData.size()) {
if(chunkData.size() - offset < 8) {
debug("Shorten::File::read() -- Truncated AIFF chunk header.");
setValid(false);
return;
}
chunkID = chunkData.toUInt(offset, true);
offset += 4;
auto chunkSize = chunkData.toUInt(offset, true);
const auto chunkSize = chunkData.toUInt(offset, true);
offset += 4;
// All chunks must have an even length but the pad byte is not included in chunkSize
chunkSize += (chunkSize & 1);
const uint64_t paddedChunkSize = static_cast<uint64_t>(chunkSize) + (chunkSize & 1);
if(paddedChunkSize > chunkData.size() - offset) {
debug("Shorten::File::read() -- AIFF chunk exceeds verbatim header.");
setValid(false);
return;
}
const unsigned int chunkEnd = offset + static_cast<unsigned int>(paddedChunkSize);
switch(chunkID) {
case 0x434f4d4d /*'COMM'*/:
@@ -523,11 +536,11 @@ void Shorten::File::read(AudioProperties::ReadStyle propertiesStyle)
break;
}
// Skip all other chunks
default:
offset += chunkSize;
break;
}
offset = chunkEnd;
}
if(!sawCommonChunk) {