diff options
author | Matthias Hopf <mhopf@suse.de> | 2009-01-04 17:21:46 +0000 |
---|---|---|
committer | Matthias Hopf <mhopf@suse.de> | 2009-01-04 17:21:46 +0000 |
commit | de3b12bc7488ca43834f2840619744a9ec2c5b16 (patch) | |
tree | ddf1aefd735fa835ba9307dcdd030f51c72c42b5 | |
parent | ba5f2ab8d7209f3971ecf22ea3bc5ee43a692b5c (diff) | |
download | xine-lib-de3b12bc7488ca43834f2840619744a9ec2c5b16.tar.gz xine-lib-de3b12bc7488ca43834f2840619744a9ec2c5b16.tar.bz2 |
Fix for CVE-2008-5243.
The real_parse_headers function in demux_real.c in xine-lib 1.1.12,
and other 1.1.15 and earlier versions, relies on an untrusted input
length value to "reindex into an allocated buffer," which allows
remote attackers to cause a denial of service (crash) via a crafted
value, probably an array index error.
-rw-r--r-- | src/demuxers/demux_real.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index efb39b75f..2b0153450 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -497,7 +497,8 @@ static void real_parse_headers (demux_real_t *this) { this->audio_streams[this->num_audio_streams].index = NULL; this->audio_streams[this->num_audio_streams].mdpr = mdpr; this->num_audio_streams++; - } else if(_X_BE_32(mdpr->type_specific_data) == RA_TAG) { + } else if(_X_BE_32(mdpr->type_specific_data) == RA_TAG && + mdpr->type_specific_len >= 6) { if(this->num_audio_streams == MAX_AUDIO_STREAMS) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: maximum number of audio stream exceeded\n"); @@ -508,26 +509,30 @@ static void real_parse_headers (demux_real_t *this) { lprintf("audio version %d detected\n", version); - char *fourcc_ptr = NULL; + char *fourcc_ptr = "\0\0\0"; switch(version) { case 3: /* Version 3 header stores fourcc after meta info - cheat by reading backwards from the * end of the header instead of having to parse it all */ - fourcc_ptr = mdpr->type_specific_data + mdpr->type_specific_len - 5; + if (mdpr->type_specific_len >= 5) + fourcc_ptr = mdpr->type_specific_data + mdpr->type_specific_len - 5; break; case 4: { - const uint8_t len = *(mdpr->type_specific_data + 56); - fourcc_ptr = mdpr->type_specific_data + 58 + len; + if (mdpr->type_specific_len >= 57) { + const uint8_t len = *(mdpr->type_specific_data + 56); + if (mdpr->type_specific_len >= 62 + len) + fourcc_ptr = mdpr->type_specific_data + 58 + len; + } } break; case 5: - fourcc_ptr = mdpr->type_specific_data + 66; + if (mdpr->type_specific_len >= 70) + fourcc_ptr = mdpr->type_specific_data + 66; break; default: lprintf("unsupported audio header version %d\n", version); goto unknown; } - lprintf("fourcc = %.4s\n", fourcc_ptr); const uint32_t fourcc = _X_ME_32(fourcc_ptr); |