mirror of
https://github.com/taglib/taglib.git
synced 2026-11-05 22:18:50 -05:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user