mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
extra checking on memory allocation sizes to prevent a class of overflow attacks
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
#endif
|
||||
#endif
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/alloc.h"
|
||||
#include "protected/stream_decoder.h"
|
||||
#include "private/bitreader.h"
|
||||
#include "private/bitmath.h"
|
||||
@@ -181,7 +182,7 @@ typedef struct FLAC__StreamDecoderPrivate {
|
||||
FLAC__StreamMetadata seek_table;
|
||||
FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
|
||||
FLAC__byte *metadata_filter_ids;
|
||||
unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
|
||||
size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
|
||||
FLAC__Frame frame;
|
||||
FLAC__bool cached; /* true if there is a byte in lookahead */
|
||||
FLAC__CPUInfo cpuinfo;
|
||||
@@ -784,7 +785,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__
|
||||
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
|
||||
|
||||
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
|
||||
if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) {
|
||||
if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -843,7 +844,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__S
|
||||
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
|
||||
|
||||
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
|
||||
if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) {
|
||||
if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1325,7 +1326,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne
|
||||
* (at negative indices) for alignment purposes; we use 4
|
||||
* to keep the data well-aligned.
|
||||
*/
|
||||
tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4));
|
||||
tmp = (FLAC__int32*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/);
|
||||
if(tmp == 0) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
@@ -1350,7 +1351,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne
|
||||
|
||||
FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
|
||||
{
|
||||
unsigned i;
|
||||
size_t i;
|
||||
|
||||
FLAC__ASSERT(0 != decoder);
|
||||
FLAC__ASSERT(0 != decoder->private_);
|
||||
@@ -1471,6 +1472,11 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
|
||||
if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))
|
||||
return false; /* read_callback_ sets the state for us */
|
||||
|
||||
if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/
|
||||
return false;
|
||||
}
|
||||
|
||||
real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
|
||||
|
||||
if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
|
||||
@@ -1533,7 +1539,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
|
||||
if(!decoder->private_->is_seeking && decoder->private_->metadata_callback)
|
||||
decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
|
||||
|
||||
/* now we have to free any malloc'ed data in the block */
|
||||
/* now we have to free any malloc()ed data in the block */
|
||||
switch(type) {
|
||||
case FLAC__METADATA_TYPE_PADDING:
|
||||
break;
|
||||
@@ -1673,7 +1679,7 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_
|
||||
decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
|
||||
|
||||
/* use realloc since we may pass through here several times (e.g. after seeking) */
|
||||
if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) {
|
||||
if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1712,7 +1718,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
|
||||
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
|
||||
return false; /* read_callback_ sets the state for us */
|
||||
if(obj->vendor_string.length > 0) {
|
||||
if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) {
|
||||
if(0 == (obj->vendor_string.entry = (FLAC__byte*)safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1730,7 +1736,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
|
||||
|
||||
/* read comments */
|
||||
if(obj->num_comments > 0) {
|
||||
if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc(obj->num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
|
||||
if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1739,7 +1745,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
|
||||
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
|
||||
return false; /* read_callback_ sets the state for us */
|
||||
if(obj->comments[i].length > 0) {
|
||||
if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) {
|
||||
if(0 == (obj->comments[i].entry = (FLAC__byte*)safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1785,7 +1791,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
|
||||
obj->num_tracks = x;
|
||||
|
||||
if(obj->num_tracks > 0) {
|
||||
if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
|
||||
if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1818,7 +1824,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
|
||||
track->num_indices = (FLAC__byte)x;
|
||||
|
||||
if(track->num_indices > 0) {
|
||||
if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
|
||||
if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1855,7 +1861,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
|
||||
/* read MIME type */
|
||||
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
|
||||
return false; /* read_callback_ sets the state for us */
|
||||
if(0 == (obj->mime_type = (char*)malloc(x+1))) {
|
||||
if(0 == (obj->mime_type = (char*)safe_malloc_add_2op_(x, /*+*/1))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1868,7 +1874,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
|
||||
/* read description */
|
||||
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
|
||||
return false; /* read_callback_ sets the state for us */
|
||||
if(0 == (obj->description = (FLAC__byte*)malloc(x+1))) {
|
||||
if(0 == (obj->description = (FLAC__byte*)safe_malloc_add_2op_(x, /*+*/1))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
@@ -1897,7 +1903,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta
|
||||
/* read data */
|
||||
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
|
||||
return false; /* read_callback_ sets the state for us */
|
||||
if(0 == (obj->data = (FLAC__byte*)malloc(obj->data_length))) {
|
||||
if(0 == (obj->data = (FLAC__byte*)safe_malloc_(obj->data_length))) {
|
||||
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user