From b2602b679fa4f7a3d9d2ea8bfe8bc9298451ed60 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Fri, 28 Mar 2008 22:50:47 +0000 Subject: More checking for memory allocation failures. --- src/demuxers/demux_4xm.c | 2 +- src/demuxers/demux_avi.c | 10 ++++++++++ src/demuxers/demux_flac.c | 2 ++ src/demuxers/demux_iff.c | 10 +++++++++- src/demuxers/demux_ipmovie.c | 5 +++-- src/demuxers/demux_qt.c | 29 +++++++++++++++++++++++++++++ src/demuxers/demux_realaudio.c | 2 +- src/demuxers/demux_wav.c | 2 +- 8 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/demuxers/demux_4xm.c b/src/demuxers/demux_4xm.c index 24aee1ac4..b06651456 100644 --- a/src/demuxers/demux_4xm.c +++ b/src/demuxers/demux_4xm.c @@ -159,7 +159,7 @@ static int open_fourxm_file(demux_fourxm_t *fourxm) { /* read the whole header */ header_size = _X_LE_32(&preview[4]) - 4; header = xine_xmalloc(header_size); - if (fourxm->input->read(fourxm->input, header, header_size) != header_size) { + if (!header || fourxm->input->read(fourxm->input, header, header_size) != header_size) { free(header); return 0; } diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index 6bb0b289c..656e4662a 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.c @@ -973,6 +973,10 @@ static avi_t *AVI_init(demux_avi_t *this) { xine_waveformatex *wavex; wavex = (xine_waveformatex *)malloc(n); + if (!wavex) { + this->AVI_errno = AVI_ERR_NO_MEM; + return 0; + } memcpy((void *)wavex, hdrl_data+i, n); _x_waveformatex_le2me( wavex ); @@ -1237,6 +1241,9 @@ static avi_t *AVI_init(demux_avi_t *this) { /* read from file */ chunk_start = en = malloc (AVI->video_superindex->aIndex[j].dwSize+hdrl_len); + if (!chunk_start) + ERR_EXIT(AVI_ERR_NO_MEM); + if (this->input->seek(this->input, AVI->video_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) { lprintf("cannot seek to 0x%" PRIx64 "\n", AVI->video_superindex->aIndex[j].qwOffset); free(chunk_start); @@ -1308,6 +1315,9 @@ static avi_t *AVI_init(demux_avi_t *this) { /* read from file */ chunk_start = en = malloc (audio->audio_superindex->aIndex[j].dwSize+hdrl_len); + if (!chunk_start) + ERR_EXIT(AVI_ERR_NO_MEM); + if (this->input->seek(this->input, audio->audio_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) { lprintf("cannot seek to 0x%" PRIx64 "\n", audio->audio_superindex->aIndex[j].qwOffset); free(chunk_start); diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c index c3d547cdb..b4c5edb2d 100644 --- a/src/demuxers/demux_flac.c +++ b/src/demuxers/demux_flac.c @@ -166,6 +166,8 @@ static int open_flac_file(demux_flac_t *flac) { flac->seekpoint_count = block_length / FLAC_SEEKPOINT_SIZE; flac->seekpoints = calloc(flac->seekpoint_count, sizeof(flac_seekpoint_t)); + if (flac->seekpoint_count && !flac->seekpoints) + return 0; for (i = 0; i < flac->seekpoint_count; i++) { if (flac->input->read(flac->input, buffer, FLAC_SEEKPOINT_SIZE) != FLAC_SEEKPOINT_SIZE) return 0; diff --git a/src/demuxers/demux_iff.c b/src/demuxers/demux_iff.c index d914405db..0856eec1a 100644 --- a/src/demuxers/demux_iff.c +++ b/src/demuxers/demux_iff.c @@ -401,7 +401,7 @@ static int read_iff_chunk(demux_iff_t *this) { this->cmap_num = junk_size / PIC_SIZE_OF_COLOR_REGISTER; this->cmap = (ColorRegister *)xine_xmalloc(junk_size); this->video_send_palette = 1; - if (this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size) + if (!this->cmap || this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size) return 0; break; case IFF_GRAB_CHUNK: @@ -709,11 +709,19 @@ static int demux_iff_send_chunk(demux_plugin_t *this_gen) { /* load the whole chunk into the buffer */ if (this->audio_buffer_filled == 0) { if (this->audio_interleave_buffer_size > 0) + { this->audio_interleave_buffer = xine_xmalloc(this->audio_interleave_buffer_size); + if (!this->audio_interleave_buffer) + return this->status = DEMUX_FINISHED; + } if (this->audio_read_buffer_size > 0) + { this->audio_read_buffer = xine_xmalloc(this->audio_read_buffer_size); + if (!this->audio_read_buffer) + return this->status = DEMUX_FINISHED; + } if (this->audio_read_buffer) { if (this->input->read(this->input, this->audio_read_buffer, this->data_size) != this->data_size) { diff --git a/src/demuxers/demux_ipmovie.c b/src/demuxers/demux_ipmovie.c index cd21896c0..12640e662 100644 --- a/src/demuxers/demux_ipmovie.c +++ b/src/demuxers/demux_ipmovie.c @@ -283,9 +283,10 @@ static int process_ipmovie_chunk(demux_ipmovie_t *this) { this->bih.biWidth = _X_LE_16(&scratch[0]) * 8; this->bih.biHeight = _X_LE_16(&scratch[2]) * 8; /* set up staging area for decode map */ - this->decode_map_size = (this->bih.biWidth * this->bih.biHeight) / - (8 * 8) / 2; + this->decode_map_size = (this->bih.biWidth / 8) * (this->bih.biHeight / 8) / 2; this->decode_map = xine_xmalloc(this->decode_map_size); + if (!this->decode_map) + this->status = DEMUX_FINISHED; lprintf("video resolution: %d x %d\n", this->bih.biWidth, this->bih.biHeight); break; diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c index 695059c09..e28952b23 100644 --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -896,6 +896,11 @@ static qt_error parse_trak_atom (qt_trak *trak, current_atom_size = _X_BE_32(&trak_atom[i - 4]); current_atom = _X_BE_32(&trak_atom[i]); + if (current_atom_size > trak_atom_size - i) { + last_error = QT_NOT_A_VALID_FILE; + goto free_trak; + } + if (current_atom == TKHD_ATOM) { trak->flags = _X_BE_16(&trak_atom[i + 6]); } else if (current_atom == ELST_ATOM) { @@ -969,6 +974,10 @@ static qt_error parse_trak_atom (qt_trak *trak, trak->stsd_atoms[k].video.properties_atom_size = current_stsd_atom_size - 4; trak->stsd_atoms[k].video.properties_atom = xine_xmalloc(trak->stsd_atoms[k].video.properties_atom_size); + if (!trak->stsd_atoms[k].video.properties_atom) { + last_error = QT_NO_MEMORY; + goto free_trak; + } memcpy(trak->stsd_atoms[k].video.properties_atom, &trak_atom[atom_pos], trak->stsd_atoms[k].video.properties_atom_size); @@ -1108,6 +1117,10 @@ static qt_error parse_trak_atom (qt_trak *trak, trak->stsd_atoms[k].audio.properties_atom_size = current_stsd_atom_size - 4; trak->stsd_atoms[k].audio.properties_atom = xine_xmalloc(trak->stsd_atoms[k].audio.properties_atom_size); + if (!trak->stsd_atoms[k].audio.properties_atom) { + last_error = QT_NO_MEMORY; + goto free_trak; + } memcpy(trak->stsd_atoms[k].audio.properties_atom, &trak_atom[atom_pos], trak->stsd_atoms[k].audio.properties_atom_size); @@ -1224,6 +1237,10 @@ static qt_error parse_trak_atom (qt_trak *trak, trak->stsd_atoms[k].audio.properties_atom_size = 36; trak->stsd_atoms[k].audio.properties_atom = xine_xmalloc(trak->stsd_atoms[k].audio.properties_atom_size); + if (!trak->stsd_atoms[k].audio.properties_atom) { + last_error = QT_NO_MEMORY; + goto free_trak; + } memcpy(trak->stsd_atoms[k].audio.properties_atom, &trak_atom[atom_pos + 0x20], trak->stsd_atoms[k].audio.properties_atom_size); @@ -1245,6 +1262,10 @@ static qt_error parse_trak_atom (qt_trak *trak, (current_atom_size >= (0x4C + wave_size))) { trak->stsd_atoms[k].audio.wave_size = wave_size; trak->stsd_atoms[k].audio.wave = xine_xmalloc(wave_size); + if (!trak->stsd_atoms[k].audio.wave) { + last_error = QT_NO_MEMORY; + goto free_trak; + } memcpy(trak->stsd_atoms[k].audio.wave, &trak_atom[atom_pos + 0x4C], wave_size); _x_waveformatex_le2me(trak->stsd_atoms[k].audio.wave); @@ -1314,8 +1335,16 @@ static qt_error parse_trak_atom (qt_trak *trak, j += mp4_read_descr_len( &trak_atom[j], &len ); debug_atom_load(" decoder config is %d (0x%X) bytes long\n", len, len); + if (len > current_atom_size - (j - i)) { + last_error = QT_NOT_A_VALID_FILE; + goto free_trak; + } trak->decoder_config = realloc(trak->decoder_config, len); trak->decoder_config_len = len; + if (!trak->decoder_config) { + last_error = QT_NO_MEMORY; + goto free_trak; + } memcpy(trak->decoder_config,&trak_atom[j],len); } } diff --git a/src/demuxers/demux_realaudio.c b/src/demuxers/demux_realaudio.c index 70c9b310a..b663912b8 100644 --- a/src/demuxers/demux_realaudio.c +++ b/src/demuxers/demux_realaudio.c @@ -103,7 +103,7 @@ static int open_ra_file(demux_ra_t *this) { /* allocate for and read header data */ this->header = xine_xmalloc(this->header_size); - if (_x_demux_read_header(this->input, this->header, this->header_size) != this->header_size) { + if (!this->header || _x_demux_read_header(this->input, this->header, this->header_size) != this->header_size) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unable to read header\n"); free(this->header); return 0; diff --git a/src/demuxers/demux_wav.c b/src/demuxers/demux_wav.c index f654a0f3e..eb9b9a6ed 100644 --- a/src/demuxers/demux_wav.c +++ b/src/demuxers/demux_wav.c @@ -131,7 +131,7 @@ static int open_wav_file(demux_wav_t *this) { 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) != + if (!this->wave || this->input->read(this->input, (void *)this->wave, this->wave_size) != this->wave_size) { free (this->wave); return 0; -- cgit v1.2.3 From 30216c0016482506a11fa7f54d72d724e56fa5b3 Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Thu, 27 Mar 2008 17:27:12 +0200 Subject: read only full frames into buffer - otherwise decoder will lose trailing bytes for 24bit AIFF --- src/demuxers/demux_aiff.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index 3f2d0df11..f520219fa 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -150,7 +150,9 @@ static int open_aiff_file(demux_aiff_t *this) { (this->audio_bits / 8); this->running_time = (this->audio_frames / this->audio_sample_rate) * 1000; - this->audio_block_align = PCM_BLOCK_ALIGN; + /* we should send only complete frames to decoder, as it + * doesn't handle underconsumption yet */ + this->audio_block_align = PCM_BLOCK_ALIGN - PCM_BLOCK_ALIGN % (this->audio_bits / 8 * this->audio_channels); break; -- cgit v1.2.3 From aba07be1265b56cc777c17e09cccebe1121ef697 Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Fri, 28 Mar 2008 15:52:34 +0200 Subject: AIFF comment chunks are word-aligned, so we should seek extra byte for them --- src/demuxers/demux_aiff.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index f520219fa..b30b74910 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -46,6 +46,10 @@ #define COMM_TAG FOURCC_TAG('C', 'O', 'M', 'M') #define SSND_TAG FOURCC_TAG('S', 'S', 'N', 'D') #define APCM_TAG FOURCC_TAG('A', 'P', 'C', 'M') +#define NAME_TAG FOURCC_TAG('N', 'A', 'M', 'E') +#define AUTH_TAG FOURCC_TAG('A', 'U', 'T', 'H') +#define COPY_TAG FOURCC_TAG('(', 'c', ')', ' ') +#define ANNO_TAG FOURCC_TAG('A', 'N', 'N', 'O') #define PREAMBLE_SIZE 8 #define AIFF_SIGNATURE_SIZE 12 @@ -157,6 +161,11 @@ static int open_aiff_file(demux_aiff_t *this) { break; } else { + /* if chunk contains metadata, it will be word-aligned (as seen at sox and ffmpeg) */ + if ( ((chunk_type == NAME_TAG) || (chunk_type==AUTH_TAG) || + (chunk_type == COPY_TAG) || (chunk_type==ANNO_TAG)) && (chunk_size&1)) + chunk_size++; + /* unrecognized; skip it */ this->input->seek(this->input, chunk_size, SEEK_CUR); } -- cgit v1.2.3 From 8fd1e52ecdd12b6e8b6ad920e47702201aeafb4b Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Thu, 27 Mar 2008 17:29:00 +0200 Subject: take into account CPU endianness when converting 24bit=>16bit samples --- src/libxineadec/xine_lpcm_decoder.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 8d8f23a05..9587da6e8 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -189,11 +189,23 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { while (n >= 0) { if ( stream_be ) { - *d++ = s[0]; - *d++ = s[1]; + if ( stream_be == this->cpu_be ) { + *d++ = s[0]; + *d++ = s[1]; + } else { + *d++ = s[1]; + *d++ = s[0]; + } } else { - *d++ = s[1]; - *d++ = s[2]; + if ( stream_be == this->cpu_be ) { + *d++ = s[1]; + *d++ = s[2]; + } + else + { + *d++ = s[2]; + *d++ = s[1]; + } } s += 3; -- cgit v1.2.3 From 7d7b7eb2f71df2e90e4100348993966e5c26d022 Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Fri, 28 Mar 2008 17:00:38 +0200 Subject: fix overreading from input buffer and report lost bytes in lpcm decoder --- src/libxineadec/xine_lpcm_decoder.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libxineadec/xine_lpcm_decoder.c b/src/libxineadec/xine_lpcm_decoder.c index 9587da6e8..eeed7ba35 100644 --- a/src/libxineadec/xine_lpcm_decoder.c +++ b/src/libxineadec/xine_lpcm_decoder.c @@ -187,7 +187,7 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { uint8_t *d = (uint8_t *)audio_buffer->mem; int n = buf->size; - while (n >= 0) { + while (n >= 3) { if ( stream_be ) { if ( stream_be == this->cpu_be ) { *d++ = s[0]; @@ -211,6 +211,10 @@ static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { s += 3; n -= 3; } + + if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf->size ) + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes\n", (int)(buf->size - (d - (uint8_t*)audio_buffer->mem))/2*3); + } else { memcpy (audio_buffer->mem, sample_buffer, buf->size); } -- cgit v1.2.3 From 11da081690da7a299909dfba0a6ad913dc11a3e3 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Fri, 28 Mar 2008 22:50:47 +0000 Subject: Changelog entries for the AIFF & LPCM fixes. --- ChangeLog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 4f2c4d857..e2f9b3131 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ xine-lib (1.1.11.1) 2008-??-?? 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 ". + * Don't try to play partial 24-bit AIFF frames (decoder would lose data). + * Fixed handling of AIFF comment chunks. + * LPCM fixes: input over-reading, conversion of 24-bit samples. xine-lib (1.1.11) 2008-03-19 * Security fixes: -- cgit v1.2.3 From fd4cb7f8687ded5d128cd8a63df99d69201f1b9a Mon Sep 17 00:00:00 2001 From: Kirill Belokurov Date: Wed, 26 Mar 2008 18:01:20 +0200 Subject: calculate AIFF files samplerate from 80-bit float, fixes wrong playback of some AIFF files --- src/demuxers/demux_aiff.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/demuxers/demux_aiff.c b/src/demuxers/demux_aiff.c index b30b74910..8a2811ac6 100644 --- a/src/demuxers/demux_aiff.c +++ b/src/demuxers/demux_aiff.c @@ -84,6 +84,24 @@ typedef struct { demux_class_t demux_class; } demux_aiff_class_t; +/* converts IEEE 80bit extended into int, based on FFMPEG code */ +int extended_to_int(const unsigned char p[10]) +{ + uint64_t m = 0; + int e, i; + + for (i = 0; i < 8; i++) + m = (m<<8) + p[2+i];; + e = (((int)p[0]&0x7f)<<8) | p[1]; + if (e == 0x7fff && m) + return 0.0/0.0; + e -= 16383 + 63; + + if (p[0]&0x80) + m= -m; + return (int) ldexp(m, e); +} + /* returns 1 if the AIFF file was opened successfully, 0 otherwise */ static int open_aiff_file(demux_aiff_t *this) { @@ -91,6 +109,7 @@ static int open_aiff_file(demux_aiff_t *this) { unsigned char preamble[PREAMBLE_SIZE]; unsigned int chunk_type; unsigned int chunk_size; + unsigned char extended_sample_rate[10]; if (_x_demux_read_header(this->input, signature, AIFF_SIGNATURE_SIZE) != AIFF_SIGNATURE_SIZE) return 0; @@ -139,7 +158,8 @@ static int open_aiff_file(demux_aiff_t *this) { this->audio_channels = _X_BE_16(&buffer[0]); this->audio_frames = _X_BE_32(&buffer[2]); this->audio_bits = _X_BE_16(&buffer[6]); - this->audio_sample_rate = _X_BE_16(&buffer[0x0A]); + memcpy(&extended_sample_rate, &buffer[8], sizeof(extended_sample_rate)); + this->audio_sample_rate = extended_to_int(extended_sample_rate); this->audio_bytes_per_second = this->audio_channels * (this->audio_bits / 8) * this->audio_sample_rate; -- cgit v1.2.3 From fce031eb887d7bb72acde81396f84b384aefd765 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sat, 29 Mar 2008 14:00:57 +0000 Subject: Changelog update. --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e2f9b3131..f01743732 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,7 +6,7 @@ xine-lib (1.1.11.1) 2008-??-?? * Added a few more memory allocation checks to the above demuxers. * WAV file playback fix: don't assume that the first chunk is "fmt ". * Don't try to play partial 24-bit AIFF frames (decoder would lose data). - * Fixed handling of AIFF comment chunks. + * Fixed AIFF comment chunk handling and sample rate reading. * LPCM fixes: input over-reading, conversion of 24-bit samples. xine-lib (1.1.11) 2008-03-19 -- cgit v1.2.3