Prevent FLAC picture length overflows (#1492)

FLAC picture string and data lengths were checked with addition. On
32-bit builds, crafted lengths can wrap the cursor and cause a
four-byte read before the ByteVector allocation.

Use remaining-length checks in Picture::parse and make fixed-width
ByteVector conversions reject offsets at or beyond the buffer.
This commit is contained in:
Acts1631
2026-11-04 17:17:34 +01:00
committed by GitHub
parent 1819fda480
commit 8fe8b8235b
2 changed files with 9 additions and 5 deletions
+3 -3
View File
@@ -72,7 +72,7 @@ bool FLAC::Picture::parse(const ByteVector &data)
pos += 4;
unsigned int mimeTypeLength = data.toUInt(pos);
pos += 4;
if(pos + mimeTypeLength + 24 > data.size()) {
if(mimeTypeLength > data.size() - pos - 24) {
debug("Invalid picture block.");
return false;
}
@@ -80,7 +80,7 @@ bool FLAC::Picture::parse(const ByteVector &data)
pos += mimeTypeLength;
unsigned int descriptionLength = data.toUInt(pos);
pos += 4;
if(pos + descriptionLength + 20 > data.size()) {
if(descriptionLength > data.size() - pos - 20) {
debug("Invalid picture block.");
return false;
}
@@ -96,7 +96,7 @@ bool FLAC::Picture::parse(const ByteVector &data)
pos += 4;
unsigned int dataLength = data.toUInt(pos);
pos += 4;
if(pos + dataLength > data.size()) {
if(dataLength > data.size() - pos) {
debug("Invalid picture block.");
return false;
}
+6 -2
View File
@@ -134,8 +134,12 @@ T toNumber(const ByteVector &v, size_t offset, bool mostSignificantByteFirst)
const bool isBigEndian = Utils::systemByteOrder() == Utils::BigEndian;
const bool swap = mostSignificantByteFirst != isBigEndian;
if(offset + sizeof(T) > v.size())
return toNumber<T>(v, offset, v.size() - offset, mostSignificantByteFirst);
if(offset >= v.size())
return toNumber<T>(v, offset, 0, mostSignificantByteFirst);
const size_t remaining = v.size() - offset;
if(sizeof(T) > remaining)
return toNumber<T>(v, offset, remaining, mostSignificantByteFirst);
// Uses memcpy instead of reinterpret_cast to avoid an alignment exception.
T tmp;