From 3d10293ee056d8833967b5b04597c547fd041ef1 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 24 Mar 2008 23:32:59 +0000 Subject: Start 1.1.11.1. Also add a few post-release changelog entries to 1.1.11 for completeness. --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index b26128624..bc9ef1c81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +xine-lib (1.1.11.1) 2008-??-?? + xine-lib (1.1.11) 2008-03-19 * Security fixes: - Array Indexing Vulnerability in sdpplin_parse(). (CVE-2008-0073) @@ -20,6 +22,8 @@ xine-lib (1.1.11) 2008-03-19 it for functions like subtitle file detection must instead use file:// MRLs; if they don't, we consider them to be buggy.) * Fixed long delay when closing stream on dual core systems [Bug #33] + * DVD playback improvement: don't trust the file sizes. + * Build fixes for use with recent ffmpeg. xine-lib (1.1.10.1) 2008-02-07 * Security fixes: -- cgit v1.2.3 From a6f1d697255078f31f718a7918974233da3d7bf3 Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Mon, 24 Mar 2008 17:14:44 +0200 Subject: WAV demuxer: search for the 'fmt ' chunk instead of assuming it's the first one (fixes playback of some files) --HG-- extra : transplant_source : %F0N%EC%A4v%94%CA%1F%05%E3%E2%AC%5D8-%18c%AD%B1%E4 --- src/demuxers/demux_wav.c | 87 +++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c index 9b46336fe..f654a0f3e 100644 --- a/src/demuxers/demux_wav.c +++ b/src/demuxers/demux_wav.c @@ -41,9 +41,11 @@ #include "bswap.h" #include "group_audio.h" -#define WAV_SIGNATURE_SIZE 16 +#define WAV_SIGNATURE_SIZE 12 /* this is the hex value for 'data' */ #define data_TAG 0x61746164 +/* this is the hex value for 'fmt ' */ +#define fmt_TAG 0x20746D66 #define PCM_BLOCK_ALIGN 1024 #define PREFERED_BLOCK_SIZE 4096 @@ -73,30 +75,62 @@ typedef struct { static int demux_wav_get_stream_length (demux_plugin_t *this_gen); +/* searches for the chunk with the given tag from the beginning of WAV file + * returns 1 if chunk was found, 0 otherwise, + * fills chunk_size and chunk_pos if chunk was found + * NOTE: chunk_pos is set to the position of the first byte of chunk data */ +static int find_chunk_by_tag(demux_wav_t *this, const uint32_t given_chunk_tag, + uint32_t *found_chunk_size, off_t *found_chunk_pos) { + uint32_t chunk_tag; + uint32_t chunk_size; + uint8_t chunk_preamble[8]; + + /* search for the chunks from the start of the WAV file */ + this->input->seek(this->input, WAV_SIGNATURE_SIZE, SEEK_SET); + + while (1) { + if (this->input->read(this->input, chunk_preamble, 8) != 8) { + return 0; + } + + chunk_tag = _X_LE_32(&chunk_preamble[0]); + chunk_size = _X_LE_32(&chunk_preamble[4]); + + if (chunk_tag == given_chunk_tag) { + if (found_chunk_size) + *found_chunk_size = _X_LE_32(&chunk_preamble[4]); + if (found_chunk_pos) + *found_chunk_pos = this->input->get_current_pos(this->input); + return 1; + } else { + this->input->seek(this->input, chunk_size, SEEK_CUR); + } + } +} + /* returns 1 if the WAV file was opened successfully, 0 otherwise */ static int open_wav_file(demux_wav_t *this) { uint8_t signature[WAV_SIGNATURE_SIZE]; uint32_t chunk_tag; uint32_t chunk_size; uint8_t chunk_preamble[8]; + off_t wave_pos; /* check the signature */ if (_x_demux_read_header(this->input, signature, WAV_SIGNATURE_SIZE) != WAV_SIGNATURE_SIZE) return 0; - if (memcmp(signature, "RIFF", 4) || memcmp(&signature[8], "WAVEfmt ", 8) ) + if (memcmp(signature, "RIFF", 4) || memcmp(&signature[8], "WAVE", 4) ) return 0; - /* file is qualified; skip over the header bytes in the stream */ - this->input->seek(this->input, WAV_SIGNATURE_SIZE, SEEK_SET); - - /* go after the format structure */ - if (this->input->read(this->input, - (unsigned char *)&this->wave_size, 4) != 4) + /* search for the 'fmt ' chunk first */ + wave_pos = 0; + if (find_chunk_by_tag(this, fmt_TAG, &this->wave_size, &wave_pos)==0) return 0; - this->wave_size = le2me_32(this->wave_size); + + this->input->seek(this->input, wave_pos, SEEK_SET); this->wave = xine_xmalloc( this->wave_size ); - + if (this->input->read(this->input, (void *)this->wave, this->wave_size) != this->wave_size) { free (this->wave); @@ -113,28 +147,21 @@ static int open_wav_file(demux_wav_t *this) { return 0; } - /* traverse through the chunks to find the 'data' chunk */ + /* search for the 'data' chunk */ this->data_start = this->data_size = 0; - while (this->data_start == 0) { - - if (this->input->read(this->input, chunk_preamble, 8) != 8) { - free (this->wave); - return 0; - } - chunk_tag = _X_LE_32(&chunk_preamble[0]); - chunk_size = _X_LE_32(&chunk_preamble[4]); - - if (chunk_tag == data_TAG) { - this->data_start = this->input->get_current_pos(this->input); - /* Get the data length from the file itself, instead of the data - * TAG, for broken files */ - this->data_size = this->input->get_length(this->input); - } else { - this->input->seek(this->input, chunk_size, SEEK_CUR); - } + if (find_chunk_by_tag(this, data_TAG, &this->data_size, &this->data_start)==0) + { + free (this->wave); + return 0; + } + else + { + /* Get the data length from the file itself, instead of the data + * TAG, for broken files */ + this->input->seek(this->input, this->data_start, SEEK_SET); + this->data_size = this->input->get_length(this->input); + return 1; } - - return 1; } static int demux_wav_send_chunk(demux_plugin_t *this_gen) { -- cgit v1.2.3 From 9377b41750ebf6e79b3631b4f3c0224ad2cad855 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 24 Mar 2008 23:34:20 +0000 Subject: Changelog entry for the WAV demuxer fix. --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index bc9ef1c81..35fd29347 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ xine-lib (1.1.11.1) 2008-??-?? + * WAV file playback fix: don't assume that the first chunk is "fmt ". xine-lib (1.1.11) 2008-03-19 * Security fixes: -- cgit v1.2.3 From 7a29f15cf90a3629185ef1f3987e24a3910785db Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sun, 23 Mar 2008 01:51:28 +0000 Subject: Check for failure of various memory allocations. (SA29484) Ref. http://aluigi.altervista.org/adv/xinehof-adv.txt --- ChangeLog | 3 ++ src/demuxers/demux_film.c | 5 +++ src/demuxers/demux_flv.c | 16 ++++++-- src/demuxers/demux_qt.c | 85 +++++++++++++++++++++++++------------------ src/demuxers/demux_real.c | 6 ++- src/demuxers/demux_wc3movie.c | 11 +++++- src/demuxers/ebml.c | 5 +++ 7 files changed, 89 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35fd29347..af30be981 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,7 @@ xine-lib (1.1.11.1) 2008-??-?? + * Security fixes: + - Heap overflows in FLV, Qt, Real, WC3Movie, Matroska and FILM demuxers. + * Added a few more memory allocation checks to the above demuxers. * WAV file playback fix: don't assume that the first chunk is "fmt ". xine-lib (1.1.11) 2008-03-19 diff --git a/src/demuxers/demux_film.c b/src/demuxers/demux_film.c index 13036afc1..349c2578f 100644 --- a/src/demuxers/demux_film.c +++ b/src/demuxers/demux_film.c @@ -257,6 +257,8 @@ static int open_film_file(demux_film_t *film) { film->sample_count = _X_BE_32(&film_header[i + 12]); film->sample_table = xine_xmalloc(film->sample_count * sizeof(film_sample_t)); + if (!film->sample_table) + goto film_abort; for (j = 0; j < film->sample_count; j++) { film->sample_table[j].sample_offset = @@ -333,11 +335,14 @@ static int open_film_file(demux_film_t *film) { free(film->interleave_buffer); film->interleave_buffer = xine_xmalloc(film->sample_table[0].sample_size); + if (!film->interleave_buffer) + goto film_abort; } break; default: xine_log(film->stream->xine, XINE_LOG_MSG, _("unrecognized FILM chunk\n")); + film_abort: free (film->interleave_buffer); free (film->sample_table); free (film_header); diff --git a/src/demuxers/demux_flv.c b/src/demuxers/demux_flv.c index a1f0b3a7b..15afe221d 100644 --- a/src/demuxers/demux_flv.c +++ b/src/demuxers/demux_flv.c @@ -85,7 +85,7 @@ typedef struct { off_t filesize; flv_index_entry_t *index; - int num_indices; + unsigned int num_indices; unsigned int cur_pts; @@ -209,7 +209,7 @@ static int parse_flv_var(demux_flv_t *this, unsigned char *end = buf + size; char *str; unsigned char type; - int len, num; + unsigned int len, num; if (size < 1) return 0; @@ -283,6 +283,8 @@ static int parse_flv_var(demux_flv_t *this, str = tmp + 2; tmp += len + 2; len = parse_flv_var(this, tmp, end-tmp, str, len); + if (!len) + return 0; tmp += len; } if (*tmp++ != FLV_DATA_TYPE_ENDOBJECT) @@ -298,6 +300,8 @@ static int parse_flv_var(demux_flv_t *this, str = tmp + 2; tmp += len + 2; len = parse_flv_var(this, tmp, end-tmp, str, len); + if (!len) + return 0; tmp += len; } break; @@ -310,6 +314,8 @@ static int parse_flv_var(demux_flv_t *this, if (this->index) free(this->index); this->index = xine_xmalloc(num*sizeof(flv_index_entry_t)); + if (!this->index) + return 0; this->num_indices = num; } for (num = 0; num < this->num_indices && tmp < end; num++) { @@ -326,6 +332,8 @@ static int parse_flv_var(demux_flv_t *this, if (this->index) free(this->index); this->index = xine_xmalloc(num*sizeof(flv_index_entry_t)); + if (!this->index) + return 0; this->num_indices = num; } for (num = 0; num < this->num_indices && tmp < end; num++) { @@ -339,6 +347,8 @@ static int parse_flv_var(demux_flv_t *this, } while (num-- && tmp < end) { len = parse_flv_var(this, tmp, end-tmp, NULL, 0); + if (!len) + return 0; tmp += len; } break; @@ -360,7 +370,7 @@ static void parse_flv_script(demux_flv_t *this, int size) { unsigned char *end = buf + size; int len; - if (this->input->read(this->input, buf, size ) != size) { + if (!buf || this->input->read(this->input, buf, size ) != size) { this->status = DEMUX_FINISHED; free(buf); return; diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index a55a0aef3..1be93abd9 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -739,38 +739,52 @@ static void parse_meta_atom(qt_info *info, unsigned char *meta_atom) { if (current_atom == ART_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; info->artist = xine_xmalloc(string_size); - strncpy(info->artist, &meta_atom[i + 20], string_size - 1); - info->artist[string_size - 1] = 0; + if (info->artist) { + strncpy(info->artist, &meta_atom[i + 20], string_size - 1); + info->artist[string_size - 1] = 0; + } } else if (current_atom == NAM_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; info->name = xine_xmalloc(string_size); - strncpy(info->name, &meta_atom[i + 20], string_size - 1); - info->name[string_size - 1] = 0; + if (info->name) { + strncpy(info->name, &meta_atom[i + 20], string_size - 1); + info->name[string_size - 1] = 0; + } } else if (current_atom == ALB_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; info->album = xine_xmalloc(string_size); - strncpy(info->album, &meta_atom[i + 20], string_size - 1); - info->album[string_size - 1] = 0; + if (info->album) { + strncpy(info->album, &meta_atom[i + 20], string_size - 1); + info->album[string_size - 1] = 0; + } } else if (current_atom == GEN_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; info->genre = xine_xmalloc(string_size); - strncpy(info->genre, &meta_atom[i + 20], string_size - 1); - info->genre[string_size - 1] = 0; + if (info->genre) { + strncpy(info->genre, &meta_atom[i + 20], string_size - 1); + info->genre[string_size - 1] = 0; + } } else if (current_atom == TOO_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; info->comment = xine_xmalloc(string_size); - strncpy(info->comment, &meta_atom[i + 20], string_size - 1); - info->comment[string_size - 1] = 0; + if (info->comment) { + strncpy(info->comment, &meta_atom[i + 20], string_size - 1); + info->comment[string_size - 1] = 0; + } } else if (current_atom == WRT_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; info->composer = xine_xmalloc(string_size); - strncpy(info->composer, &meta_atom[i + 20], string_size - 1); - info->composer[string_size - 1] = 0; + if (info->composer) { + strncpy(info->composer, &meta_atom[i + 20], string_size - 1); + info->composer[string_size - 1] = 0; + } } else if (current_atom == DAY_ATOM) { string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; info->year = xine_xmalloc(string_size); - strncpy(info->year, &meta_atom[i + 20], string_size - 1); - info->year[string_size - 1] = 0; + if (info->year) { + strncpy(info->year, &meta_atom[i + 20], string_size - 1); + info->year[string_size - 1] = 0; + } } } @@ -1549,32 +1563,29 @@ static qt_error parse_reference_atom (reference_t *ref, current_atom = _X_BE_32(&ref_atom[i]); if (current_atom == RDRF_ATOM) { + size_t string_size = _X_BE_32(&ref_atom[i + 12]); + size_t url_offset = 0; + + if (string_size >= current_atom_size || i + string_size >= ref_atom_size) + return QT_NOT_A_VALID_FILE; /* if the URL starts with "http://", copy it */ - if (strncmp(&ref_atom[i + 16], "http://", 7) == 0 - || strncmp(&ref_atom[i + 16], "rtsp://", 7) == 0) { + if ( memcmp(&ref_atom[i + 16], "http://", 7) && + memcmp(&ref_atom[i + 16], "rtsp://", 7) && + base_mrl ) + url_offset = strlen(base_mrl); - /* URL is spec'd to terminate with a NULL; don't trust it */ - ref->url = xine_xmalloc(_X_BE_32(&ref_atom[i + 12]) + 1); - strncpy(ref->url, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12])); - ref->url[_X_BE_32(&ref_atom[i + 12]) - 1] = '\0'; + /* otherwise, append relative URL to base MRL */ + string_size += url_offset; - } else { + ref->url = xine_xmalloc(string_size + 1); - int string_size; + if ( url_offset ) + strcpy(ref->url, base_mrl); - if (base_mrl) - string_size = strlen(base_mrl) + _X_BE_32(&ref_atom[i + 12]) + 1; - else - string_size = _X_BE_32(&ref_atom[i + 12]) + 1; + memcpy(ref->url + url_offset, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12])); - /* otherwise, append relative URL to base MRL */ - ref->url = xine_xmalloc(string_size); - if (base_mrl) - strcpy(ref->url, base_mrl); - strncat(ref->url, &ref_atom[i + 16], _X_BE_32(&ref_atom[i + 12])); - ref->url[string_size - 1] = '\0'; - } + ref->url[string_size] = '\0'; debug_atom_load(" qt rdrf URL reference:\n %s\n", ref->url); @@ -1993,8 +2004,12 @@ static void parse_moov_atom(qt_info *info, unsigned char *moov_atom, info->references = (reference_t *)realloc(info->references, info->reference_count * sizeof(reference_t)); - parse_reference_atom(&info->references[info->reference_count - 1], - &moov_atom[i - 4], info->base_mrl); + error = parse_reference_atom(&info->references[info->reference_count - 1], + &moov_atom[i - 4], info->base_mrl); + if (error != QT_OK) { + info->last_error = error; + return; + } } else { debug_atom_load(" qt: unknown atom into the moov atom (0x%08X)\n", current_atom); diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index 9206bfc74..c5096b210 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -175,7 +175,8 @@ static void real_parse_index(demux_real_t *this) { off_t original_pos = this->input->get_current_pos(this->input); unsigned char index_chunk_header[INDEX_CHUNK_HEADER_SIZE]; unsigned char index_record[INDEX_RECORD_SIZE]; - int i, entries, stream_num; + int i; + unsigned int entries, stream_num; real_index_entry_t **index; while(next_index_chunk) { @@ -230,10 +231,11 @@ static void real_parse_index(demux_real_t *this) { } } - if(index && entries) { + if(index && entries) /* Allocate memory for index */ *index = xine_xmalloc(entries * sizeof(real_index_entry_t)); + if(index && entries && *index) { /* Read index */ for(i = 0; i < entries; i++) { if(this->input->read(this->input, index_record, INDEX_RECORD_SIZE) diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c index 596d47f4a..1a839924d 100644 --- a/src/demuxers/demux_wc3movie.c +++ b/src/demuxers/demux_wc3movie.c @@ -389,6 +389,12 @@ static int open_mve_file(demux_mve_t *this) { /* load the palette chunks */ this->palettes = xine_xmalloc(this->number_of_shots * PALETTE_SIZE * sizeof(palette_entry_t)); + + if (!this->shot_offsets || !this->palettes) { + free (this->shot_offsets); + return 0; + } + for (i = 0; i < this->number_of_shots; i++) { /* make sure there was a valid palette chunk preamble */ if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != @@ -460,8 +466,9 @@ static int open_mve_file(demux_mve_t *this) { case BNAM_TAG: /* load the name into the stream attributes */ - title = realloc (title, chunk_size); - if (this->input->read(this->input, title, chunk_size) != chunk_size) { + free (title); + title = malloc (chunk_size); + if (!title || this->input->read(this->input, title, chunk_size) != chunk_size) { free (title); free (this->palettes); free (this->shot_offsets); diff --git a/src/demuxers/ebml.c b/src/demuxers/ebml.c index ac44aecd7..cc8173c26 100644 --- a/src/demuxers/ebml.c +++ b/src/demuxers/ebml.c @@ -424,10 +424,15 @@ int ebml_check_header(ebml_parser_t *ebml) { case EBML_ID_DOCTYPE: { char *text = malloc(elem.len + 1); + if (!text) + return 0; text[elem.len] = '\0'; if (!ebml_read_ascii (ebml, &elem, text)) + { + free (text); return 0; + } lprintf("doctype: %s\n", text); if (ebml->doctype) -- cgit v1.2.3 From 2f6bd99aa3b9e9bee0601f90ab6e772c011c50ad Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sun, 23 Mar 2008 15:52:33 +0000 Subject: Replace various malloc(x*sizeof(y)) with calloc(x,sizeof(y)). --- src/demuxers/demux_film.c | 2 +- src/demuxers/demux_flac.c | 2 +- src/demuxers/demux_flv.c | 4 ++-- src/demuxers/demux_mpgaudio.c | 2 +- src/demuxers/demux_qt.c | 38 ++++++++++++++++++-------------------- src/demuxers/demux_real.c | 2 +- src/demuxers/demux_tta.c | 2 +- src/demuxers/demux_vmd.c | 2 +- src/demuxers/demux_wc3movie.c | 4 ++-- 9 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/demuxers/demux_film.c b/src/demuxers/demux_film.c index 349c2578f..60365ab4d 100644 --- a/src/demuxers/demux_film.c +++ b/src/demuxers/demux_film.c @@ -256,7 +256,7 @@ static int open_film_file(demux_film_t *film) { film->frequency = _X_BE_32(&film_header[i + 8]); film->sample_count = _X_BE_32(&film_header[i + 12]); film->sample_table = - xine_xmalloc(film->sample_count * sizeof(film_sample_t)); + calloc(film->sample_count, sizeof(film_sample_t)); if (!film->sample_table) goto film_abort; for (j = 0; j < film->sample_count; j++) { diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c index f6544bb67..c3d547cdb 100644 --- a/src/demuxers/demux_flac.c +++ b/src/demuxers/demux_flac.c @@ -164,7 +164,7 @@ static int open_flac_file(demux_flac_t *flac) { case 3: lprintf ("SEEKTABLE metadata, %d bytes\n", block_length); flac->seekpoint_count = block_length / FLAC_SEEKPOINT_SIZE; - flac->seekpoints = xine_xmalloc(flac->seekpoint_count * + flac->seekpoints = calloc(flac->seekpoint_count, sizeof(flac_seekpoint_t)); for (i = 0; i < flac->seekpoint_count; i++) { if (flac->input->read(flac->input, buffer, FLAC_SEEKPOINT_SIZE) != FLAC_SEEKPOINT_SIZE) diff --git a/src/demuxers/demux_flv.c b/src/demuxers/demux_flv.c index 15afe221d..0d18783c2 100644 --- a/src/demuxers/demux_flv.c +++ b/src/demuxers/demux_flv.c @@ -313,7 +313,7 @@ static int parse_flv_var(demux_flv_t *this, if (!this->index || this->num_indices != num) { if (this->index) free(this->index); - this->index = xine_xmalloc(num*sizeof(flv_index_entry_t)); + this->index = calloc(num, sizeof(flv_index_entry_t)); if (!this->index) return 0; this->num_indices = num; @@ -331,7 +331,7 @@ static int parse_flv_var(demux_flv_t *this, if (!this->index || this->num_indices != num) { if (this->index) free(this->index); - this->index = xine_xmalloc(num*sizeof(flv_index_entry_t)); + this->index = calloc(num, sizeof(flv_index_entry_t)); if (!this->index) return 0; this->num_indices = num; diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c index 56759dd4b..c7af1c508 100644 --- a/src/demuxers/demux_mpgaudio.c +++ b/src/demuxers/demux_mpgaudio.c @@ -460,7 +460,7 @@ static vbri_header_t* parse_vbri_header(mpg_audio_frame_t *frame, lprintf("entry_frames: %d\n", vbri->entry_frames); if ((ptr + (vbri->toc_entries + 1) * vbri->entry_size) >= (buf + bufsize)) return 0; - vbri->toc = xine_xmalloc (sizeof(int) * (vbri->toc_entries + 1)); + vbri->toc = calloc (vbri->toc_entries + 1, sizeof (int)); if (!vbri->toc) { free (vbri); return NULL; diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 1be93abd9..695059c09 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -911,8 +911,8 @@ static qt_error parse_trak_atom (qt_trak *trak, debug_atom_load(" qt elst atom (edit list atom): %d entries\n", trak->edit_list_count); - trak->edit_list_table = (edit_list_table_t *)xine_xmalloc( - trak->edit_list_count * sizeof(edit_list_table_t)); + trak->edit_list_table = (edit_list_table_t *)calloc( + trak->edit_list_count, sizeof(edit_list_table_t)); if (!trak->edit_list_table) { last_error = QT_NO_MEMORY; goto free_trak; @@ -947,7 +947,7 @@ static qt_error parse_trak_atom (qt_trak *trak, /* allocate space for each of the properties unions */ trak->stsd_atoms_count = _X_BE_32(&trak_atom[i + 8]); - trak->stsd_atoms = xine_xmalloc(trak->stsd_atoms_count * sizeof(properties_t)); + trak->stsd_atoms = calloc(trak->stsd_atoms_count, sizeof(properties_t)); if (!trak->stsd_atoms) { last_error = QT_NO_MEMORY; goto free_trak; @@ -1345,8 +1345,8 @@ static qt_error parse_trak_atom (qt_trak *trak, /* allocate space and load table only if sample size is 0 */ if (trak->sample_size == 0) { - trak->sample_size_table = (unsigned int *)malloc( - trak->sample_size_count * sizeof(unsigned int)); + trak->sample_size_table = (unsigned int *)calloc( + trak->sample_size_count, sizeof(unsigned int)); if (!trak->sample_size_table) { last_error = QT_NO_MEMORY; goto free_trak; @@ -1376,8 +1376,8 @@ static qt_error parse_trak_atom (qt_trak *trak, debug_atom_load(" qt stss atom (sample sync atom): %d sync samples\n", trak->sync_sample_count); - trak->sync_sample_table = (unsigned int *)malloc( - trak->sync_sample_count * sizeof(unsigned int)); + trak->sync_sample_table = (unsigned int *)calloc( + trak->sync_sample_count, sizeof(unsigned int)); if (!trak->sync_sample_table) { last_error = QT_NO_MEMORY; goto free_trak; @@ -1405,8 +1405,8 @@ static qt_error parse_trak_atom (qt_trak *trak, debug_atom_load(" qt stco atom (32-bit chunk offset atom): %d chunk offsets\n", trak->chunk_offset_count); - trak->chunk_offset_table = (int64_t *)malloc( - trak->chunk_offset_count * sizeof(int64_t)); + trak->chunk_offset_table = (int64_t *)calloc( + trak->chunk_offset_count, sizeof(int64_t)); if (!trak->chunk_offset_table) { last_error = QT_NO_MEMORY; goto free_trak; @@ -1433,8 +1433,8 @@ static qt_error parse_trak_atom (qt_trak *trak, debug_atom_load(" qt co64 atom (64-bit chunk offset atom): %d chunk offsets\n", trak->chunk_offset_count); - trak->chunk_offset_table = (int64_t *)malloc( - trak->chunk_offset_count * sizeof(int64_t)); + trak->chunk_offset_table = (int64_t *)calloc( + trak->chunk_offset_count, sizeof(int64_t)); if (!trak->chunk_offset_table) { last_error = QT_NO_MEMORY; goto free_trak; @@ -1464,8 +1464,8 @@ static qt_error parse_trak_atom (qt_trak *trak, debug_atom_load(" qt stsc atom (sample-to-chunk atom): %d entries\n", trak->sample_to_chunk_count); - trak->sample_to_chunk_table = (sample_to_chunk_table_t *)malloc( - trak->sample_to_chunk_count * sizeof(sample_to_chunk_table_t)); + trak->sample_to_chunk_table = (sample_to_chunk_table_t *)calloc( + trak->sample_to_chunk_count, sizeof(sample_to_chunk_table_t)); if (!trak->sample_to_chunk_table) { last_error = QT_NO_MEMORY; goto free_trak; @@ -1499,8 +1499,8 @@ static qt_error parse_trak_atom (qt_trak *trak, debug_atom_load(" qt stts atom (time-to-sample atom): %d entries\n", trak->time_to_sample_count); - trak->time_to_sample_table = (time_to_sample_table_t *)malloc( - (trak->time_to_sample_count+1) * sizeof(time_to_sample_table_t)); + trak->time_to_sample_table = (time_to_sample_table_t *)calloc( + trak->time_to_sample_count+1, sizeof(time_to_sample_table_t)); if (!trak->time_to_sample_table) { last_error = QT_NO_MEMORY; goto free_trak; @@ -1697,8 +1697,7 @@ static qt_error build_frame_table(qt_trak *trak, /* in this case, the total number of frames is equal to the number of * entries in the sample size table */ trak->frame_count = trak->sample_size_count; - trak->frames = (qt_frame *)malloc( - trak->frame_count * sizeof(qt_frame)); + trak->frames = (qt_frame *)calloc(trak->frame_count, sizeof(qt_frame)); if (!trak->frames) return QT_NO_MEMORY; trak->current_frame = 0; @@ -1710,7 +1709,7 @@ static qt_error build_frame_table(qt_trak *trak, pts_index_countdown = trak->time_to_sample_table[pts_index].count; - media_id_counts = xine_xmalloc(trak->stsd_atoms_count * sizeof(int)); + media_id_counts = calloc(trak->stsd_atoms_count, sizeof(int)); if (!media_id_counts) return QT_NO_MEMORY; memset(media_id_counts, 0, trak->stsd_atoms_count * sizeof(int)); @@ -1848,8 +1847,7 @@ static qt_error build_frame_table(qt_trak *trak, /* in this case, the total number of frames is equal to the number of * chunks */ trak->frame_count = trak->chunk_offset_count; - trak->frames = (qt_frame *)malloc( - trak->frame_count * sizeof(qt_frame)); + trak->frames = (qt_frame *)calloc(trak->frame_count, sizeof(qt_frame)); if (!trak->frames) return QT_NO_MEMORY; diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index c5096b210..60075d750 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -233,7 +233,7 @@ static void real_parse_index(demux_real_t *this) { if(index && entries) /* Allocate memory for index */ - *index = xine_xmalloc(entries * sizeof(real_index_entry_t)); + *index = calloc(entries, sizeof(real_index_entry_t)); if(index && entries && *index) { /* Read index */ diff --git a/src/demuxers/demux_tta.c b/src/demuxers/demux_tta.c index f6eadd652..f0dd2612e 100644 --- a/src/demuxers/demux_tta.c +++ b/src/demuxers/demux_tta.c @@ -87,7 +87,7 @@ static int open_tta_file(demux_tta_t *this) { return 0; } - this->seektable = xine_xmalloc(sizeof(uint32_t)*this->totalframes); + this->seektable = calloc(this->totalframes, sizeof(uint32_t)); this->input->read(this->input, this->seektable, sizeof(uint32_t)*this->totalframes); /* Skip the CRC32 */ diff --git a/src/demuxers/demux_vmd.c b/src/demuxers/demux_vmd.c index 8b0087417..416e86f39 100644 --- a/src/demuxers/demux_vmd.c +++ b/src/demuxers/demux_vmd.c @@ -168,7 +168,7 @@ static int open_vmd_file(demux_vmd_t *this) { return 0; } - this->frame_table = xine_xmalloc(this->frame_count * sizeof(vmd_frame_t)); + this->frame_table = calloc(this->frame_count, sizeof(vmd_frame_t)); current_offset = this->data_start = _X_LE_32(&vmd_header[20]); this->data_size = toc_offset - this->data_start; diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c index 1a839924d..b3dcb775f 100644 --- a/src/demuxers/demux_wc3movie.c +++ b/src/demuxers/demux_wc3movie.c @@ -378,7 +378,7 @@ static int open_mve_file(demux_mve_t *this) { this->number_of_shots = _X_LE_32(&preamble[0]); /* allocate space for the shot offset index and set offsets to 0 */ - this->shot_offsets = xine_xmalloc(this->number_of_shots * sizeof(off_t)); + this->shot_offsets = calloc(this->number_of_shots, sizeof(off_t)); this->current_shot = 0; for (i = 0; i < this->number_of_shots; i++) this->shot_offsets[i] = 0; @@ -387,7 +387,7 @@ static int open_mve_file(demux_mve_t *this) { this->input->seek(this->input, 12, SEEK_CUR); /* load the palette chunks */ - this->palettes = xine_xmalloc(this->number_of_shots * PALETTE_SIZE * + this->palettes = calloc(this->number_of_shots, PALETTE_SIZE * sizeof(palette_entry_t)); if (!this->shot_offsets || !this->palettes) { -- cgit v1.2.3 From 38c7aa2581a80ca5fda454af74e0bd12f4f159b6 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Tue, 25 Mar 2008 14:45:05 +0000 Subject: Improve security bug fix description & add its CVE no. --- ChangeLog | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index af30be981..4f2c4d857 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ xine-lib (1.1.11.1) 2008-??-?? * Security fixes: - - Heap overflows in FLV, Qt, Real, WC3Movie, Matroska and FILM demuxers. + - Integer overflows in FLV, Qt, Real, WC3Movie, Matroska and FILM + demuxers, allowing remote attackers to trigger heap overflows and + possibly execute arbitrary code. (CVE-2008-1482) * Added a few more memory allocation checks to the above demuxers. * WAV file playback fix: don't assume that the first chunk is "fmt ". -- cgit v1.2.3 From 1bedd052b17aab0fc6b1b85a727207648908095b Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Wed, 26 Mar 2008 18:54:55 +0000 Subject: Be more careful with malloc(x+1), particularly on 32-bit. --- src/demuxers/demux_matroska.c | 14 ++++---------- src/demuxers/ebml.c | 25 +++++++++++++++++-------- src/demuxers/ebml.h | 2 ++ 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/demuxers/demux_matroska.c b/src/demuxers/demux_matroska.c index 63b6ea3c8..7643a2cb4 100644 --- a/src/demuxers/demux_matroska.c +++ b/src/demuxers/demux_matroska.c @@ -1179,13 +1179,10 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { break; case MATROSKA_ID_TR_CODECID: { - char *codec_id = malloc (elem.len + 1); + char *codec_id = ebml_alloc_read_ascii (ebml, &elem); lprintf("CodecID\n"); - if (!ebml_read_ascii(ebml, &elem, codec_id)) { - free(codec_id); + if (!codec_id) return 0; - } - codec_id[elem.len] = '\0'; track->codec_id = codec_id; } break; @@ -1203,13 +1200,10 @@ static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { break; case MATROSKA_ID_TR_LANGUAGE: { - char *language = malloc (elem.len + 1); + char *language = ebml_alloc_read_ascii (ebml, &elem); lprintf("Language\n"); - if (!ebml_read_ascii(ebml, &elem, language)) { - free(language); + if (!language) return 0; - } - language[elem.len] = '\0'; track->language = language; } break; diff --git a/src/demuxers/ebml.c b/src/demuxers/ebml.c index cc8173c26..0c633643f 100644 --- a/src/demuxers/ebml.c +++ b/src/demuxers/ebml.c @@ -318,6 +318,22 @@ int ebml_read_utf8 (ebml_parser_t *ebml, ebml_elem_t *elem, char *str) { return ebml_read_ascii (ebml, elem, str); } +char *ebml_alloc_read_ascii (ebml_parser_t *ebml, ebml_elem_t *elem) +{ + char *text; + if (elem->len >= 4096) + return NULL; + text = malloc(elem->len + 1); + if (text) + { + text[elem->len] = '\0'; + if (ebml_read_ascii (ebml, &elem, text)) + return text; + free (text); + } + return NULL; +} + int ebml_read_date (ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date) { return ebml_read_sint (ebml, elem, date); } @@ -423,17 +439,10 @@ int ebml_check_header(ebml_parser_t *ebml) { } case EBML_ID_DOCTYPE: { - char *text = malloc(elem.len + 1); + char *text = ebml_alloc_read_ascii (ebml, &elem); if (!text) return 0; - text[elem.len] = '\0'; - if (!ebml_read_ascii (ebml, &elem, text)) - { - free (text); - return 0; - } - lprintf("doctype: %s\n", text); if (ebml->doctype) free (ebml->doctype); diff --git a/src/demuxers/ebml.h b/src/demuxers/ebml.h index 35078c502..a38515544 100644 --- a/src/demuxers/ebml.h +++ b/src/demuxers/ebml.h @@ -91,6 +91,8 @@ int ebml_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem, char *str); int ebml_read_utf8(ebml_parser_t *ebml, ebml_elem_t *elem, char *str); +char *ebml_alloc_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem); + int ebml_read_date(ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date); int ebml_read_master(ebml_parser_t *ebml, ebml_elem_t *elem); -- cgit v1.2.3