summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2008-03-26 21:16:07 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2008-03-26 21:16:07 +0000
commit427bd5660454820ab4de3c569b1f4727977c23ef (patch)
treea3047e3eec2c78f52c5de18dcd1e36eefbc277d5
parentfd417a2e958b0f38be68a09c1316324f1e9589c4 (diff)
parent1bedd052b17aab0fc6b1b85a727207648908095b (diff)
downloadxine-lib-427bd5660454820ab4de3c569b1f4727977c23ef.tar.gz
xine-lib-427bd5660454820ab4de3c569b1f4727977c23ef.tar.bz2
Merge from 1.1.
-rw-r--r--ChangeLog10
-rw-r--r--src/demuxers/demux_film.c5
-rw-r--r--src/demuxers/demux_flv.c16
-rw-r--r--src/demuxers/demux_matroska.c14
-rw-r--r--src/demuxers/demux_qt.c29
-rw-r--r--src/demuxers/demux_real.c6
-rw-r--r--src/demuxers/demux_vmd.c2
-rw-r--r--src/demuxers/demux_wav.c87
-rw-r--r--src/demuxers/demux_wc3movie.c11
-rw-r--r--src/demuxers/ebml.c24
-rw-r--r--src/demuxers/ebml.h4
11 files changed, 146 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index f78399c3f..49cbe6179 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -64,6 +64,14 @@ xine-lib (1.1.90) (Unreleased)
* Report more video output capabilities via (port)->get_capabilities():
colour controls, zooming, colour keying.
+xine-lib (1.1.11.1) 2008-??-??
+ * Security fixes:
+ - 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 ".
+
xine-lib (1.1.11) 2008-03-19
* Security fixes:
- Array Indexing Vulnerability in sdpplin_parse(). (CVE-2008-0073)
@@ -86,6 +94,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:
diff --git a/src/demuxers/demux_film.c b/src/demuxers/demux_film.c
index 193d8850b..f7b514e4b 100644
--- a/src/demuxers/demux_film.c
+++ b/src/demuxers/demux_film.c
@@ -260,6 +260,8 @@ static int open_film_file(demux_film_t *film) {
film->sample_count = _X_BE_32(&film_header[i + 12]);
film->sample_table =
xine_xcalloc(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 =
@@ -335,11 +337,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 38855c027..e111468aa 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_xcalloc(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_xcalloc(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_matroska.c b/src/demuxers/demux_matroska.c
index ec932aacb..fe6703dbf 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/demux_qt.c b/src/demuxers/demux_qt.c
index ecd2c319a..15b2773eb 100644
--- a/src/demuxers/demux_qt.c
+++ b/src/demuxers/demux_qt.c
@@ -746,8 +746,10 @@ static char *parse_data_atom(const uint8_t *data_atom) {
}
alloc_str = xine_xmalloc(alloc_size);
- xine_fast_memcpy(alloc_str, &data_atom[16], alloc_size-1);
- alloc_str[alloc_size-1] = '\0';
+ if (alloc_str) {
+ xine_fast_memcpy(alloc_str, &data_atom[16], alloc_size-1);
+ alloc_str[alloc_size-1] = '\0';
+ }
debug_meta_load("demux_qt: got a string of size %zd (%s)\n", alloc_size, alloc_str);
@@ -954,8 +956,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;
@@ -1399,8 +1401,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;
@@ -1430,8 +1432,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;
@@ -1614,6 +1616,9 @@ static qt_error parse_reference_atom (reference_t *ref,
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 ( memcmp(&ref_atom[i + 16], "http://", 7) &&
memcmp(&ref_atom[i + 16], "rtsp://", 7) &&
@@ -2054,8 +2059,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;
+ }
break;
default:
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index 41c6fb4a2..7b5f7530d 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_xcalloc(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_vmd.c b/src/demuxers/demux_vmd.c
index c2902eac1..d1d98f534 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_wav.c b/src/demuxers/demux_wav.c
index b8f0d0194..0c17c836a 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) {
diff --git a/src/demuxers/demux_wc3movie.c b/src/demuxers/demux_wc3movie.c
index bb9a40306..5be59b12b 100644
--- a/src/demuxers/demux_wc3movie.c
+++ b/src/demuxers/demux_wc3movie.c
@@ -387,6 +387,12 @@ static int open_mve_file(demux_mve_t *this) {
/* load the palette chunks */
this->palettes = xine_xcalloc(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) !=
@@ -458,8 +464,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 41a91371e..97bf0a615 100644
--- a/src/demuxers/ebml.c
+++ b/src/demuxers/ebml.c
@@ -310,7 +310,25 @@ 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) {
return ebml_read_ascii (ebml, elem, str);
}
+#endif
+
+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;
+}
+#if 0
int ebml_read_date (ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date) {
return ebml_read_sint (ebml, elem, date);
}
@@ -414,10 +432,8 @@ int ebml_check_header(ebml_parser_t *ebml) {
}
case EBML_ID_DOCTYPE: {
- char *text = malloc(elem.len + 1);
-
- text[elem.len] = '\0';
- if (!ebml_read_ascii (ebml, &elem, text))
+ char *text = ebml_alloc_read_ascii (ebml, &elem);
+ if (!text)
return 0;
lprintf("doctype: %s\n", text);
diff --git a/src/demuxers/ebml.h b/src/demuxers/ebml.h
index 31d825e35..a090bb130 100644
--- a/src/demuxers/ebml.h
+++ b/src/demuxers/ebml.h
@@ -93,7 +93,11 @@ int ebml_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem, char *str);
#if 0
int ebml_read_utf8(ebml_parser_t *ebml, ebml_elem_t *elem, char *str);
+#endif
+
+char *ebml_alloc_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem);
+#if 0
int ebml_read_date(ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date);
#endif