diff -u xine-lib-1.1.15/debian/changelog xine-lib-1.1.15/debian/changelog --- xine-lib-1.1.15/debian/changelog +++ xine-lib-1.1.15/debian/changelog @@ -1,3 +1,32 @@ +xine-lib (1.1.15-0ubuntu3.1) intrepid-security; urgency=low + + * SECURITY UPDATE: backported security fixes from upstream xine-lib hg repo: + - debian/patches/01_SECURITY_invalid_track_type.dpatch: Avoid segfault on + invalid track type in Matroska files. + - debian/patches/02_SECURITY_ffmpeg_video_overflow.dpatch: Heap buffer + overflow in the ffmpeg video decoder. + - debian/patches/03_SECURITY_ffmpeg_audio_overflow.dpatch: Integer overflow + in the ffmpeg audio decoder + - debian/patches/04_SECURITY_cdda_server_overflow.dpatch: Integer overflow + in the the CDDA server. + - debian/patches/05_SECURITY_CVE-2008-5234.dpatch: Heap overflow and + unchecked malloc in Quicktime atom parsing. (CVE-2008-5234, CVE-2008-5242) + - debian/patches/06_SECURITY_CVE-2008-5236.dpatch: Buffer overflows in + Matroska, Real and RealAudio demuxers. (CVE-2008-5236) + - debian/patches/07_SECURITY_CVE-2008-5237.dpatch: Integer overflows in + MNG and QT demuxers. (CVE-2008-5237) + - debian/patches/08_SECURITY_CVE-2008-5239.dpatch: Out-of-bounds reads and + heap-based buffer overflows from unchecked or incompletely-checked read + function results. (CVE-2008-5239) + - debian/patches/09_SECURITY_CVE-2008-5240.dpatch: Unchecked malloc using + untrusted values. (CVE-2008-5240) + - debian/patches/10_SECURITY_CVE-2008-5241.dpatch: Integer underflow in qt + compressed atom handling. (CVE-2008-5241) + - debian/patches/11_SECURITY_CVE-2008-5243.dpatch: Buffer indexing using + untrusted or unchecked values. (CVE-2008-5243) + + -- Marc Deslauriers Wed, 21 Jan 2009 08:32:25 -0500 + xine-lib (1.1.15-0ubuntu3) intrepid; urgency=low * Changed xine-engine/buffer.h to use __inline__ diff -u xine-lib-1.1.15/debian/patches/00list xine-lib-1.1.15/debian/patches/00list --- xine-lib-1.1.15/debian/patches/00list +++ xine-lib-1.1.15/debian/patches/00list @@ -1,0 +2,11 @@ +01_SECURITY_invalid_track_type +02_SECURITY_ffmpeg_video_overflow +03_SECURITY_ffmpeg_audio_overflow +04_SECURITY_cdda_server_overflow +05_SECURITY_CVE-2008-5234 +06_SECURITY_CVE-2008-5236 +07_SECURITY_CVE-2008-5237 +08_SECURITY_CVE-2008-5239 +09_SECURITY_CVE-2008-5240 +10_SECURITY_CVE-2008-5241 +11_SECURITY_CVE-2008-5243 only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/03_SECURITY_ffmpeg_audio_overflow.dpatch +++ xine-lib-1.1.15/debian/patches/03_SECURITY_ffmpeg_audio_overflow.dpatch @@ -0,0 +1,20 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 03_SECURITY_ffmpeg_audio_overflow.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix integer overflow in the ffmpeg audio decoder +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=0779a86cae2827b3325177b792b0fe1dc5b5706d;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/combined/ffmpeg/ff_audio_decoder.c xine-lib-1.1.15/src/combined/ffmpeg/ff_audio_decoder.c +--- xine-lib-1.1.15~/src/combined/ffmpeg/ff_audio_decoder.c 2008-07-15 19:13:03.000000000 -0400 ++++ xine-lib-1.1.15/src/combined/ffmpeg/ff_audio_decoder.c 2009-01-15 09:48:39.000000000 -0500 +@@ -249,6 +249,8 @@ + + if (extradata + data_len > this->size) + break; /* abort early - extradata length is bad */ ++ if (extradata > INT_MAX - data_len) ++ break;/*integer overflow*/ + + this->context->extradata_size = data_len; + this->context->extradata = malloc(this->context->extradata_size + only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/07_SECURITY_CVE-2008-5237.dpatch +++ xine-lib-1.1.15/debian/patches/07_SECURITY_CVE-2008-5237.dpatch @@ -0,0 +1,75 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 07_SECURITY_CVE-2008-5237.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix integer overflows in MNG and QT demuxers. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=9c97a9a9ba17a487116a198d80a74ec7879aa801;style=gitweb +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=65f524e14623;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_mng.c xine-lib-1.1.15/src/demuxers/demux_mng.c +--- xine-lib-1.1.15~/src/demuxers/demux_mng.c 2008-08-13 12:33:04.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_mng.c 2009-01-15 09:57:02.000000000 -0500 +@@ -104,7 +104,12 @@ + static mng_bool mymng_read_stream(mng_handle mngh, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread){ + demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); + +- *bytesread = this->input->read(this->input, buffer, size); ++ off_t n = this->input->read(this->input, buffer, size); ++ if (n < 0) { ++ *bytesread = 0; ++ return MNG_FALSE; ++ } ++ *bytesread = n; + + return MNG_TRUE; + } +@@ -112,6 +117,9 @@ + static mng_bool mymng_process_header(mng_handle mngh, mng_uint32 width, mng_uint32 height){ + demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); + ++ if (width > 0x8000 || height > 0x8000) ++ return MNG_FALSE; ++ + this->bih.biWidth = (width + 7) & ~7; + this->bih.biHeight = height; + this->left_edge = (this->bih.biWidth - width) / 2; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_qt.c xine-lib-1.1.15/src/demuxers/demux_qt.c +--- xine-lib-1.1.15~/src/demuxers/demux_qt.c 2009-01-15 09:56:39.000000000 -0500 ++++ xine-lib-1.1.15/src/demuxers/demux_qt.c 2009-01-15 09:56:59.000000000 -0500 +@@ -1597,13 +1597,16 @@ + qt_atom current_atom; + unsigned int current_atom_size; + ++ if (ref_atom_size >= 0x80000000) ++ return QT_NOT_A_VALID_FILE; ++ + /* initialize reference atom */ + ref->url = NULL; + ref->data_rate = 0; + ref->qtim_version = 0; + + /* traverse through the atom looking for the key atoms */ +- for (i = ATOM_PREAMBLE_SIZE; i < ref_atom_size - 4; i++) { ++ for (i = ATOM_PREAMBLE_SIZE; i + 4 < ref_atom_size; i++) { + + current_atom_size = _X_BE_32(&ref_atom[i - 4]); + current_atom = _X_BE_32(&ref_atom[i]); +@@ -1612,7 +1615,7 @@ + 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) ++ if (string_size >= current_atom_size || string_size >= ref_atom_size - i) + return QT_NOT_A_VALID_FILE; + + /* if the URL starts with "http://", copy it */ +@@ -1620,6 +1623,8 @@ + memcmp(&ref_atom[i + 16], "rtsp://", 7) && + base_mrl ) + url_offset = strlen(base_mrl); ++ if (url_offset >= 0x80000000) ++ return QT_NOT_A_VALID_FILE; + + /* otherwise, append relative URL to base MRL */ + string_size += url_offset; only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/01_SECURITY_invalid_track_type.dpatch +++ xine-lib-1.1.15/debian/patches/01_SECURITY_invalid_track_type.dpatch @@ -0,0 +1,28 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 01_SECURITY_invalid_track_type.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: Avoid segfault on invalid track type in Matroska files. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=7b472fa486db;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_matroska.c xine-lib-1.1.15/src/demuxers/demux_matroska.c +--- xine-lib-1.1.15~/src/demuxers/demux_matroska.c 2008-08-13 12:33:04.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_matroska.c 2009-01-15 09:45:38.000000000 -0500 +@@ -1479,9 +1479,14 @@ + break; + } + +- if (init_codec) ++ if (init_codec) { ++ if (! track->fifo) { ++ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, ++ "demux_matroska: Error: fifo not set up for track of type type %" PRIu32 "\n", track->track_type); ++ return 0; ++ } + init_codec(this, track); +- ++ } + } + } + only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/09_SECURITY_CVE-2008-5240.dpatch +++ xine-lib-1.1.15/debian/patches/09_SECURITY_CVE-2008-5240.dpatch @@ -0,0 +1,179 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 09_SECURITY_CVE-2008-5240.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix unchecked malloc using untrusted values. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=01753933e6647ed29226f18e4489ce034b569d65;style=gitweb +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib/?cmd=changeset;node=071dc93156e6940a7f1b8bb38762d521dd5731e8;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_real.c xine-lib-1.1.15/src/demuxers/demux_real.c +--- xine-lib-1.1.15~/src/demuxers/demux_real.c 2009-01-21 08:29:29.000000000 -0500 ++++ xine-lib-1.1.15/src/demuxers/demux_real.c 2009-01-21 08:29:41.000000000 -0500 +@@ -265,8 +265,12 @@ + this->input->seek(this->input, original_pos, SEEK_SET); + } + +-static mdpr_t *real_parse_mdpr(const char *data) { +- mdpr_t *mdpr=malloc(sizeof(mdpr_t)); ++static mdpr_t *real_parse_mdpr(const char *data, const unsigned int size) ++{ ++ if (size < 38) ++ return NULL; ++ ++ mdpr_t *mdpr=calloc(sizeof(mdpr_t), 1); + + mdpr->stream_number=_X_BE_16(&data[2]); + mdpr->max_bit_rate=_X_BE_32(&data[4]); +@@ -278,17 +282,29 @@ + mdpr->duration=_X_BE_32(&data[28]); + + mdpr->stream_name_size=data[32]; ++ if (size < 38 + mdpr->stream_name_size) ++ goto fail; + mdpr->stream_name=malloc(mdpr->stream_name_size+1); ++ if (!mdpr->stream_name) ++ goto fail; + memcpy(mdpr->stream_name, &data[33], mdpr->stream_name_size); + mdpr->stream_name[(int)mdpr->stream_name_size]=0; + + mdpr->mime_type_size=data[33+mdpr->stream_name_size]; ++ if (size < 38 + mdpr->stream_name_size + mdpr->mime_type_size) ++ goto fail; + mdpr->mime_type=malloc(mdpr->mime_type_size+1); ++ if (!mdpr->mime_type) ++ goto fail; + memcpy(mdpr->mime_type, &data[34+mdpr->stream_name_size], mdpr->mime_type_size); + mdpr->mime_type[(int)mdpr->mime_type_size]=0; + + mdpr->type_specific_len=_X_BE_32(&data[34+mdpr->stream_name_size+mdpr->mime_type_size]); ++ if (size < 38 + mdpr->stream_name_size + mdpr->mime_type_size + mdpr->type_specific_data) ++ goto fail; + mdpr->type_specific_data=malloc(mdpr->type_specific_len); ++ if (!mdpr->type_specific_data) ++ goto fail; + memcpy(mdpr->type_specific_data, + &data[38+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); + +@@ -308,6 +324,13 @@ + #endif + + return mdpr; ++ ++fail: ++ free (mdpr->stream_name); ++ free (mdpr->mime_type); ++ free (mdpr->type_specific_data); ++ free (mdpr); ++ return NULL; + } + + static void real_free_mdpr (mdpr_t *mdpr) { +@@ -435,9 +458,14 @@ + case MDPR_TAG: + case CONT_TAG: + { ++ if (chunk_size < PREAMBLE_SIZE+1) { ++ this->status = DEMUX_FINISHED; ++ return; ++ } + chunk_size -= PREAMBLE_SIZE; + uint8_t *const chunk_buffer = malloc(chunk_size); +- if (this->input->read(this->input, chunk_buffer, chunk_size) != ++ if (! chunk_buffer || ++ this->input->read(this->input, chunk_buffer, chunk_size) != + chunk_size) { + free (chunk_buffer); + this->status = DEMUX_FINISHED; +@@ -480,9 +508,14 @@ + continue; + } + +- mdpr_t *const mdpr = real_parse_mdpr (chunk_buffer); ++ mdpr_t *const mdpr = real_parse_mdpr (chunk_buffer, chunk_size); + + lprintf ("parsing type specific data...\n"); ++ if (!mdpr) { ++ free (chunk_buffer); ++ this->status = DEMUX_FINISHED; ++ return; ++ } + if(!strcmp(mdpr->mime_type, "audio/X-MP3-draft-00")) { + lprintf ("mpeg layer 3 audio detected...\n"); + +diff -urNad xine-lib-1.1.15~/src/input/libreal/rmff.c xine-lib-1.1.15/src/input/libreal/rmff.c +--- xine-lib-1.1.15~/src/input/libreal/rmff.c 2008-05-19 10:15:43.000000000 -0400 ++++ xine-lib-1.1.15/src/input/libreal/rmff.c 2009-01-21 08:29:41.000000000 -0500 +@@ -330,12 +330,14 @@ + return prop; + } + +-static rmff_mdpr_t *rmff_scan_mdpr(const char *data) { +- +- rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t)); ++static rmff_mdpr_t *rmff_scan_mdpr(const char *data) ++{ ++ rmff_mdpr_t *mdpr = calloc(sizeof(rmff_mdpr_t), 1); + + mdpr->object_id=_X_BE_32(data); + mdpr->size=_X_BE_32(&data[4]); ++ if (mdpr->size < 46) ++ goto fail; + mdpr->object_version=_X_BE_16(&data[8]); + if (mdpr->object_version != 0) + { +@@ -351,21 +353,40 @@ + mdpr->duration=_X_BE_32(&data[36]); + + mdpr->stream_name_size=data[40]; ++ if (mdpr->size < 46 + mdpr->stream_name_size) ++ goto fail; + mdpr->stream_name = malloc(mdpr->stream_name_size+1); ++ if (!mdpr->stream_name) ++ goto fail; + memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size); + mdpr->stream_name[mdpr->stream_name_size]=0; + + mdpr->mime_type_size=data[41+mdpr->stream_name_size]; ++ if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size) ++ goto fail; + mdpr->mime_type = malloc(mdpr->mime_type_size+1); ++ if (!mdpr->mime_type) ++ goto fail; + memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size); + mdpr->mime_type[mdpr->mime_type_size]=0; + + mdpr->type_specific_len=_X_BE_32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]); ++ if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size + mdpr->type_specific_data) ++ goto fail; + mdpr->type_specific_data = malloc(mdpr->type_specific_len); ++ if (!mdpr->type_specific_data) ++ goto fail; + memcpy(mdpr->type_specific_data, + &data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); + + return mdpr; ++ ++fail: ++ free (mdpr->stream_name); ++ free (mdpr->mime_type); ++ free (mdpr->type_specific_data); ++ free (mdpr); ++ return NULL; + } + + static rmff_cont_t *rmff_scan_cont(const char *data) { +@@ -463,8 +484,11 @@ + break; + case MDPR_TAG: + mdpr=rmff_scan_mdpr(ptr); +- chunk_size=mdpr->size; +- header->streams[mdpr->stream_number]=mdpr; ++ if (mdpr) /* FIXME: what to do if NULL? */ ++ { ++ chunk_size=mdpr->size; ++ header->streams[mdpr->stream_number]=mdpr; ++ } + break; + case CONT_TAG: + header->cont=rmff_scan_cont(ptr); only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/10_SECURITY_CVE-2008-5241.dpatch +++ xine-lib-1.1.15/debian/patches/10_SECURITY_CVE-2008-5241.dpatch @@ -0,0 +1,20 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 10_SECURITY_CVE-2008-5241.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix integer underflow in qt compressed atom handling. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=a57d5ef86b65bcc195a5358125fdb34e10a37bb4;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_qt.c xine-lib-1.1.15/src/demuxers/demux_qt.c +--- xine-lib-1.1.15~/src/demuxers/demux_qt.c 2009-01-15 10:00:08.000000000 -0500 ++++ xine-lib-1.1.15/src/demuxers/demux_qt.c 2009-01-15 10:00:16.000000000 -0500 +@@ -2208,7 +2208,7 @@ + } + + /* check if moov is compressed */ +- if (_X_BE_32(&moov_atom[12]) == CMOV_ATOM) { ++ if (_X_BE_32(&moov_atom[12]) == CMOV_ATOM && moov_atom_size >= 0x28) { + + info->compressed_header = 1; + only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/02_SECURITY_ffmpeg_video_overflow.dpatch +++ xine-lib-1.1.15/debian/patches/02_SECURITY_ffmpeg_video_overflow.dpatch @@ -0,0 +1,112 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 02_SECURITY_ffmpeg_video_overflow.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix heap buffer overflow in the ffmpeg video decoder. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=ffb2e82d7bb77e87492734f72c2e5d21fb9ad2c0;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/combined/ffmpeg/ff_video_decoder.c xine-lib-1.1.15/src/combined/ffmpeg/ff_video_decoder.c +--- xine-lib-1.1.15~/src/combined/ffmpeg/ff_video_decoder.c 2008-07-16 17:01:56.000000000 -0400 ++++ xine-lib-1.1.15/src/combined/ffmpeg/ff_video_decoder.c 2009-01-15 09:47:43.000000000 -0500 +@@ -606,6 +606,10 @@ + su = this->av_frame->data[1]; + sv = this->av_frame->data[2]; + ++ /* Some segfaults & heap corruption have been observed with img->height, ++ * so we use this->bih.biHeight instead (which is the displayed height) ++ */ ++ + if (this->context->pix_fmt == PIX_FMT_YUV410P) { + + yuv9_to_yv12( +@@ -626,7 +630,7 @@ + img->pitches[2], + /* width x height */ + img->width, +- img->height); ++ this->bih.biHeight); + + } else if (this->context->pix_fmt == PIX_FMT_YUV411P) { + +@@ -648,7 +652,7 @@ + img->pitches[2], + /* width x height */ + img->width, +- img->height); ++ this->bih.biHeight); + + } else if (this->context->pix_fmt == PIX_FMT_RGBA32) { + +@@ -656,7 +660,7 @@ + uint32_t *argb_pixels; + uint32_t argb; + +- for(y = 0; y < img->height; y++) { ++ for(y = 0; y < this->bih.biHeight; y++) { + argb_pixels = (uint32_t *)sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; +@@ -684,7 +688,7 @@ + uint8_t *src; + uint16_t pixel16; + +- for(y = 0; y < img->height; y++) { ++ for(y = 0; y < this->bih.biHeight; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; +@@ -713,7 +717,7 @@ + uint8_t *src; + uint16_t pixel16; + +- for(y = 0; y < img->height; y++) { ++ for(y = 0; y < this->bih.biHeight; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; +@@ -741,7 +745,7 @@ + int x, plane_ptr = 0; + uint8_t *src; + +- for(y = 0; y < img->height; y++) { ++ for(y = 0; y < this->bih.biHeight; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; +@@ -765,7 +769,7 @@ + int x, plane_ptr = 0; + uint8_t *src; + +- for(y = 0; y < img->height; y++) { ++ for(y = 0; y < this->bih.biHeight; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + uint8_t r, g, b; +@@ -808,7 +812,7 @@ + v_palette[x] = COMPUTE_V(r, g, b); + } + +- for(y = 0; y < img->height; y++) { ++ for(y = 0; y < this->bih.biHeight; y++) { + src = sy; + for(x = 0; x < img->width; x++) { + pixel = *src++; +@@ -825,7 +829,7 @@ + + } else { + +- for (y=0; yheight; y++) { ++ for (y = 0; y < this->bih.biHeight; y++) { + xine_fast_memcpy (dy, sy, img->width); + + dy += img->pitches[0]; +@@ -833,7 +837,7 @@ + sy += this->av_frame->linesize[0]; + } + +- for (y=0; y<(img->height/2); y++) { ++ for (y = 0; y < this->bih.biHeight / 2; y++) { + + if (this->context->pix_fmt != PIX_FMT_YUV444P) { + only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/06_SECURITY_CVE-2008-5236.dpatch +++ xine-lib-1.1.15/debian/patches/06_SECURITY_CVE-2008-5236.dpatch @@ -0,0 +1,143 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 06_SECURITY_CVE-2008-5236.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix buffer overflows in Matroska, Real and RealAudio demuxers. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=e38bb4b22431123997a16a186fe8beb4edcfef87;style=gitweb +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=8e125da9ecbe;style=gitweb +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=b01a02595343;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_matroska.c xine-lib-1.1.15/src/demuxers/demux_matroska.c +--- xine-lib-1.1.15~/src/demuxers/demux_matroska.c 2009-01-15 09:53:14.000000000 -0500 ++++ xine-lib-1.1.15/src/demuxers/demux_matroska.c 2009-01-15 09:53:36.000000000 -0500 +@@ -607,6 +607,8 @@ + int i; + uint8_t *data; + ++ if (track->codec_private_len < 3) ++ return; + nb_lace = track->codec_private[0]; + if (nb_lace != 2) + return; +@@ -614,6 +616,8 @@ + frame[0] = track->codec_private[1]; + frame[1] = track->codec_private[2]; + frame[2] = track->codec_private_len - frame[0] - frame[1] - 3; ++ if (frame[2] < 0) ++ return; + + data = track->codec_private + 3; + for (i = 0; i < 3; i++) { +@@ -1179,7 +1183,12 @@ + break; + + case MATROSKA_ID_TR_CODECPRIVATE: { +- char *codec_private = malloc (elem.len); ++ char *codec_private; ++ if (elem.len >= 0x80000000) ++ return 0; ++ codec_private = malloc (elem.len); ++ if (! codec_private) ++ return 0; + lprintf("CodecPrivate\n"); + if (!ebml_read_binary(ebml, &elem, codec_private)) { + free(codec_private); +@@ -1283,12 +1292,14 @@ + if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_VFW_FOURCC)) { + xine_bmiheader *bih; + +- lprintf("MATROSKA_CODEC_ID_V_VFW_FOURCC\n"); +- bih = (xine_bmiheader*)track->codec_private; +- _x_bmiheader_le2me(bih); ++ if (track->codec_private_len >= sizeof(xine_bmiheader)) { ++ lprintf("MATROSKA_CODEC_ID_V_VFW_FOURCC\n"); ++ bih = (xine_bmiheader*)track->codec_private; ++ _x_bmiheader_le2me(bih); + +- track->buf_type = _x_fourcc_to_buf_video(bih->biCompression); +- init_codec = init_codec_video; ++ track->buf_type = _x_fourcc_to_buf_video(bih->biCompression); ++ init_codec = init_codec_video; ++ } + + } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_UNCOMPRESSED)) { + } else if ((!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG4_SP)) || +@@ -1394,11 +1405,13 @@ + xine_waveformatex *wfh; + lprintf("MATROSKA_CODEC_ID_A_ACM\n"); + +- wfh = (xine_waveformatex*)track->codec_private; +- _x_waveformatex_le2me(wfh); ++ if (track->codec_private_len >= sizeof(xine_waveformatex)) { ++ wfh = (xine_waveformatex*)track->codec_private; ++ _x_waveformatex_le2me(wfh); + +- track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag); +- init_codec = init_codec_audio; ++ track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag); ++ init_codec = init_codec_audio; ++ } + } else if (!strncmp(track->codec_id, MATROSKA_CODEC_ID_A_AAC, + sizeof(MATROSKA_CODEC_ID_A_AAC) - 1)) { + lprintf("MATROSKA_CODEC_ID_A_AAC\n"); +@@ -1812,6 +1825,11 @@ + alloc_block_data(this, len); + + /* block datas */ ++ if (! this->block_data) { ++ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, ++ "demux_matroska: memory allocation error\n"); ++ return 0; ++ } + if (this->input->read(this->input, this->block_data, len) != len) { + off_t pos = this->input->get_current_pos(this->input); + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_real.c xine-lib-1.1.15/src/demuxers/demux_real.c +--- xine-lib-1.1.15~/src/demuxers/demux_real.c 2008-08-13 12:33:04.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_real.c 2009-01-15 09:53:29.000000000 -0500 +@@ -359,9 +359,14 @@ + * stream->frame_size = stream->w / stream->sps * stream->h * stream->sps; + * but it looks pointless? the compiler will probably optimise it away, I suppose? + */ +- stream->frame_size = stream->w * stream->h; ++ if (stream->w < 32768 && stream->h < 32768) { ++ stream->frame_size = stream->w * stream->h; ++ stream->frame_buffer = calloc(stream->frame_size, 1); ++ } else { ++ stream->frame_size = 0; ++ stream->frame_buffer = NULL; ++ } + +- stream->frame_buffer = calloc(stream->frame_size, 1); + stream->frame_num_bytes = 0; + stream->sub_packet_cnt = 0; + +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_realaudio.c xine-lib-1.1.15/src/demuxers/demux_realaudio.c +--- xine-lib-1.1.15~/src/demuxers/demux_realaudio.c 2008-08-13 12:33:04.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_realaudio.c 2009-01-15 09:53:29.000000000 -0500 +@@ -202,11 +202,19 @@ + this->h = _X_BE_16 (this->header+40); + this->cfs = _X_BE_32 (this->header+24); + +- this->frame_len = this->w * this->h; +- this->frame_size = this->frame_len * sps; +- +- this->frame_buffer = calloc(this->frame_size, 1); +- _x_assert(this->frame_buffer != NULL); ++ if (this->w < 0x8000 && this->h < 0x8000) { ++ uint64_t fs; ++ this->frame_len = this->w * this->h; ++ fs = (uint64_t) this->frame_len * sps; ++ if (fs < 0x80000000) { ++ this->frame_size = fs; ++ this->frame_buffer = calloc(this->frame_size, 1); ++ } ++ } ++ if (! this->frame_buffer) { ++ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: malloc failed\n"); ++ return 0; ++ } + + if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO) + this->block_align = this->cfs; only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/08_SECURITY_CVE-2008-5239.dpatch +++ xine-lib-1.1.15/debian/patches/08_SECURITY_CVE-2008-5239.dpatch @@ -0,0 +1,591 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 08_SECURITY_CVE-2008-5239.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix out-of-bounds reads and heap-based buffer overflows from unchecked or +## DP: incompletely-checked read function results. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=7fb21abb15e5a7311a2c157721ddfab0a47090ab;style=gitweb +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=5df277a7eec373d9c9dffbf586f6a6a8e69b7d4c;style=gitweb +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=f775929597b1c10142e51674ee02e041b1b87df4;style=gitweb +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib/?cmd=changeset;node=e6efc6d566961ab231686c1ee18044f2d45a2b4a;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_aac.c xine-lib-1.1.15/src/demuxers/demux_aac.c +--- xine-lib-1.1.15~/src/demuxers/demux_aac.c 2008-07-12 16:08:43.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_aac.c 2009-01-21 08:23:04.000000000 -0500 +@@ -173,7 +173,7 @@ + buf->extra_info->input_time = (8*current_pos) / (bitrate/1000); + + bytes_read = this->input->read(this->input, buf->content, buf->max_size); +- if (bytes_read == 0) { ++ if (bytes_read <= 0) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + return this->status; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_ac3.c xine-lib-1.1.15/src/demuxers/demux_ac3.c +--- xine-lib-1.1.15~/src/demuxers/demux_ac3.c 2008-07-12 18:23:52.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_ac3.c 2009-01-21 08:23:04.000000000 -0500 +@@ -311,13 +311,7 @@ + this->frame_size); + } + +- if (buf->size == 0) { +- buf->free_buffer(buf); +- this->status = DEMUX_FINISHED; +- return this->status; +- } +- +- if (buf->size == 0) { ++ if (buf->size <= 0) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + return this->status; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_dts.c xine-lib-1.1.15/src/demuxers/demux_dts.c +--- xine-lib-1.1.15~/src/demuxers/demux_dts.c 2008-07-12 18:23:52.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_dts.c 2009-01-21 08:23:04.000000000 -0500 +@@ -272,7 +272,7 @@ + this->frame_size); + } + +- if (buf->size == 0) { ++ if (buf->size <= 0) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + return this->status; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_mpc.c xine-lib-1.1.15/src/demuxers/demux_mpc.c +--- xine-lib-1.1.15~/src/demuxers/demux_mpc.c 2008-07-12 16:08:43.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_mpc.c 2009-01-21 08:23:04.000000000 -0500 +@@ -209,7 +209,7 @@ + + /* Read data */ + bytes_read = this->input->read(this->input, buf->content, bytes_to_read); +- if(bytes_read == 0) { ++ if(bytes_read <= 0) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + return this->status; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_mpeg.c xine-lib-1.1.15/src/demuxers/demux_mpeg.c +--- xine-lib-1.1.15~/src/demuxers/demux_mpeg.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_mpeg.c 2009-01-21 08:23:17.000000000 -0500 +@@ -920,7 +920,7 @@ + if (pos == len) { + len = this->input->read(this->input, dummy_buf, sizeof(dummy_buf)); + pos = 0; +- if (len == 0) { ++ if (len <= 0) { + this->status = DEMUX_FINISHED; + break; + } +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_nsf.c xine-lib-1.1.15/src/demuxers/demux_nsf.c +--- xine-lib-1.1.15~/src/demuxers/demux_nsf.c 2008-07-12 17:32:21.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_nsf.c 2009-01-21 08:23:04.000000000 -0500 +@@ -124,7 +124,7 @@ + buf->type = BUF_AUDIO_NSF; + bytes_read = this->input->read(this->input, buf->content, buf->max_size); + +- if (bytes_read == 0) { ++ if (bytes_read <= 0) { + /* the file has been completely loaded, free the buffer and start + * sending control buffers */ + buf->free_buffer(buf); +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_ogg.c xine-lib-1.1.15/src/demuxers/demux_ogg.c +--- xine-lib-1.1.15~/src/demuxers/demux_ogg.c 2008-08-07 13:52:41.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_ogg.c 2009-01-21 08:23:04.000000000 -0500 +@@ -237,7 +237,7 @@ + while (ogg_sync_pageout(&this->oy,&this->og)!=1) { + buffer = ogg_sync_buffer(&this->oy, CHUNKSIZE); + bytes = this->input->read(this->input, buffer, CHUNKSIZE); +- if (bytes == 0) { ++ if (bytes <= 0) { + if (total == 0) { + lprintf("read_ogg_packet read nothing\n"); + return 0; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_shn.c xine-lib-1.1.15/src/demuxers/demux_shn.c +--- xine-lib-1.1.15~/src/demuxers/demux_shn.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_shn.c 2009-01-21 08:23:04.000000000 -0500 +@@ -88,7 +88,7 @@ + buf->pts = 0; + + bytes_read = this->input->read(this->input, buf->content, buf->max_size); +- if (bytes_read == 0) { ++ if (bytes_read <= 0) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + return this->status; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_slave.c xine-lib-1.1.15/src/demuxers/demux_slave.c +--- xine-lib-1.1.15~/src/demuxers/demux_slave.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_slave.c 2009-01-21 08:23:04.000000000 -0500 +@@ -90,10 +90,11 @@ + /* fill the scratch buffer */ + n = this->input->read(this->input, &this->scratch[this->scratch_used], + SCRATCH_SIZE - this->scratch_used); +- this->scratch_used += n; ++ if (n > 0) ++ this->scratch_used += n; + this->scratch[this->scratch_used] = '\0'; + +- if( !n ) { ++ if (n <= 0) { + lprintf("connection closed\n"); + this->status = DEMUX_FINISHED; + return 0; +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_ts.c xine-lib-1.1.15/src/demuxers/demux_ts.c +--- xine-lib-1.1.15~/src/demuxers/demux_ts.c 2008-06-25 09:04:13.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_ts.c 2009-01-21 08:23:04.000000000 -0500 +@@ -1573,7 +1573,7 @@ + do { + read_length = this->input->read(this->input, this->buf, + PKT_SIZE * NPKT_PER_READ); +- if (read_length % PKT_SIZE) { ++ if (read_length < 0 || read_length % PKT_SIZE) { + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_ts: read returned %d bytes (not a multiple of %d!)\n", + read_length, PKT_SIZE); +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_tta.c xine-lib-1.1.15/src/demuxers/demux_tta.c +--- xine-lib-1.1.15~/src/demuxers/demux_tta.c 2008-07-12 16:08:43.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_tta.c 2009-01-21 08:23:04.000000000 -0500 +@@ -126,6 +126,10 @@ + /* buf->extra_info->input_time = this->current_sample / this->samplerate; */ + + bytes_read = this->input->read(this->input, buf->content, ( bytes_to_read > buf->max_size ) ? buf->max_size : bytes_to_read); ++ if (bytes_read < 0) { ++ this->status = DEMUX_FINISHED; ++ break; ++ } + + buf->size = bytes_read; + +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_vox.c xine-lib-1.1.15/src/demuxers/demux_vox.c +--- xine-lib-1.1.15~/src/demuxers/demux_vox.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_vox.c 2009-01-21 08:23:04.000000000 -0500 +@@ -77,7 +77,7 @@ + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_AUDIO_DIALOGIC_IMA; + bytes_read = this->input->read(this->input, buf->content, buf->max_size); +- if (bytes_read == 0) { ++ if (bytes_read <= 0) { + buf->free_buffer(buf); + this->status = DEMUX_FINISHED; + return this->status; +diff -urNad xine-lib-1.1.15~/src/input/input_dvb.c xine-lib-1.1.15/src/input/input_dvb.c +--- xine-lib-1.1.15~/src/input/input_dvb.c 2008-08-07 13:52:41.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_dvb.c 2009-01-21 08:23:04.000000000 -0500 +@@ -2602,6 +2602,10 @@ + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + int total_bytes; + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } + + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; +diff -urNad xine-lib-1.1.15~/src/input/input_dvd.c xine-lib-1.1.15/src/input/input_dvd.c +--- xine-lib-1.1.15~/src/input/input_dvd.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_dvd.c 2009-01-21 08:23:04.000000000 -0500 +@@ -850,6 +850,9 @@ + static off_t dvd_plugin_read (input_plugin_t *this_gen, char *ch_buf, off_t len) { + /* dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; */ + ++ if (len < 4) ++ return -1; ++ + /* FIXME: Tricking the demux_mpeg_block plugin */ + ch_buf[0] = 0; + ch_buf[1] = 0; +diff -urNad xine-lib-1.1.15~/src/input/input_file.c xine-lib-1.1.15/src/input/input_file.c +--- xine-lib-1.1.15~/src/input/input_file.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_file.c 2009-01-21 08:23:04.000000000 -0500 +@@ -145,6 +145,9 @@ + static off_t file_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { + file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + ++ if (len < 0) ++ return -1; ++ + #ifdef HAVE_MMAP + if ( check_mmap_file(this) ) { + off_t l = len; +@@ -166,6 +169,11 @@ + file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->type = BUF_DEMUX_BLOCK; + + #ifdef HAVE_MMAP +diff -urNad xine-lib-1.1.15~/src/input/input_gnome_vfs.c xine-lib-1.1.15/src/input/input_gnome_vfs.c +--- xine-lib-1.1.15~/src/input/input_gnome_vfs.c 2008-04-28 09:30:55.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_gnome_vfs.c 2009-01-21 08:23:04.000000000 -0500 +@@ -121,6 +121,11 @@ + off_t total_bytes; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +diff -urNad xine-lib-1.1.15~/src/input/input_http.c xine-lib-1.1.15/src/input/input_http.c +--- xine-lib-1.1.15~/src/input/input_http.c 2008-06-25 09:04:09.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_http.c 2009-01-21 08:23:04.000000000 -0500 +@@ -421,6 +421,9 @@ + + num_bytes = 0; + ++ if (nlen < 0) ++ return -1; ++ + if (this->curpos < this->preview_size) { + + if (nlen > (this->preview_size - this->curpos)) +@@ -437,7 +440,7 @@ + + n = nlen - num_bytes; + +- if (n) { ++ if (n > 0) { + int read_bytes; + read_bytes = http_plugin_read_int (this, &buf[num_bytes], n); + +@@ -503,6 +506,11 @@ + off_t total_bytes; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +@@ -554,7 +562,7 @@ + if ((origin == SEEK_CUR) && (offset >= 0)) { + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) ++ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) + return this->curpos; + } + +@@ -576,7 +584,7 @@ + offset -= this->curpos; + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) ++ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) + return this->curpos; + } + +@@ -996,6 +1004,7 @@ + this->preview_size = http_plugin_read_int (this, this->preview, MAX_PREVIEW_SIZE); + } + if (this->preview_size < 0) { ++ this->preview_size = 0; + xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno); + return -12; + } +diff -urNad xine-lib-1.1.15~/src/input/input_mms.c xine-lib-1.1.15/src/input/input_mms.c +--- xine-lib-1.1.15~/src/input/input_mms.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_mms.c 2009-01-21 08:23:04.000000000 -0500 +@@ -122,6 +122,11 @@ + + lprintf ("mms_plugin_read_block: %"PRId64" bytes...\n", todo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +diff -urNad xine-lib-1.1.15~/src/input/input_net.c xine-lib-1.1.15/src/input/input_net.c +--- xine-lib-1.1.15~/src/input/input_net.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_net.c 2009-01-21 08:23:04.000000000 -0500 +@@ -253,6 +253,9 @@ + + lprintf("reading %" PRIdMAX " bytes...\n", (intmax_t)len); + ++ if (len < 0) ++ return -1; ++ + total=0; + if (this->curpos < this->preview_size) { + n = this->preview_size - this->curpos; +@@ -288,6 +291,11 @@ + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + off_t total_bytes; + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +@@ -331,7 +339,7 @@ + if ((origin == SEEK_CUR) && (offset >= 0)) { + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) ++ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) + return this->curpos; + } + +@@ -353,7 +361,7 @@ + offset -= this->curpos; + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) ++ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) + return this->curpos; + } + +diff -urNad xine-lib-1.1.15~/src/input/input_pnm.c xine-lib-1.1.15/src/input/input_pnm.c +--- xine-lib-1.1.15~/src/input/input_pnm.c 2008-06-25 09:04:09.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_pnm.c 2009-01-21 08:23:04.000000000 -0500 +@@ -83,7 +83,8 @@ + lprintf ("pnm_plugin_read: %"PRId64" bytes ...\n", len); + + n = pnm_read (this->pnm, buf, len); +- this->curpos += n; ++ if (n >= 0) ++ this->curpos += n; + + return n; + } +@@ -96,6 +97,11 @@ + + lprintf ("pnm_plugin_read_block: %"PRId64" bytes...\n", todo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +@@ -123,10 +129,16 @@ + if ((origin == SEEK_CUR) && (offset >= 0)) { + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- this->curpos += pnm_plugin_read (this_gen, this->scratch, BUFSIZE); ++ off_t n = pnm_plugin_read (this_gen, this->scratch, BUFSIZE); ++ if (n <= 0) ++ return this->curpos; ++ this->curpos += n; + } + +- this->curpos += pnm_plugin_read (this_gen, this->scratch, offset); ++ off_t n = pnm_plugin_read (this_gen, this->scratch, offset); ++ if (n <= 0) ++ return this->curpos; ++ this->curpos += n; + } + + return this->curpos; +diff -urNad xine-lib-1.1.15~/src/input/input_pvr.c xine-lib-1.1.15/src/input/input_pvr.c +--- xine-lib-1.1.15~/src/input/input_pvr.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_pvr.c 2009-01-21 08:23:04.000000000 -0500 +@@ -424,6 +424,9 @@ + static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { + /*pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;*/ + ++ if (len < 4) ++ return -1; ++ + /* FIXME: Tricking the demux_mpeg_block plugin */ + buf[0] = 0; + buf[1] = 0; +@@ -1204,6 +1207,12 @@ + return NULL; + } + ++ buf = fifo->buffer_pool_alloc (fifo); ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer(buf); ++ return NULL; ++ } ++ + if( this->scr_tunning == -2 ) + speed = this->speed_before_pause; + +@@ -1227,7 +1236,6 @@ + + pvr_event_handler(this); + +- buf = fifo->buffer_pool_alloc (fifo); + buf->content = buf->mem; + + pthread_mutex_lock(&this->lock); +diff -urNad xine-lib-1.1.15~/src/input/input_rtp.c xine-lib-1.1.15/src/input/input_rtp.c +--- xine-lib-1.1.15~/src/input/input_rtp.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_rtp.c 2009-01-21 08:23:04.000000000 -0500 +@@ -453,6 +453,9 @@ + struct timespec timeout; + off_t copied = 0; + ++ if (length < 0) ++ return -1; ++ + while(length > 0) { + + off_t n; +@@ -524,6 +527,10 @@ + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + int total_bytes; + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } + + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; +@@ -609,11 +616,14 @@ + if (data_type == INPUT_OPTIONAL_DATA_PREVIEW) { + if (!this->preview_read_done) { + this->preview_size = rtp_plugin_read(this_gen, this->preview, MAX_PREVIEW_SIZE); ++ if (this->preview_size < 0) ++ this->preview_size = 0; + lprintf("Preview data length = %d\n", this->preview_size); + + this->preview_read_done = 1; + } +- memcpy(data, this->preview, this->preview_size); ++ if (this->preview_size) ++ memcpy(data, this->preview, this->preview_size); + return this->preview_size; + } + else { +diff -urNad xine-lib-1.1.15~/src/input/input_rtsp.c xine-lib-1.1.15/src/input/input_rtsp.c +--- xine-lib-1.1.15~/src/input/input_rtsp.c 2008-06-25 09:04:09.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_rtsp.c 2009-01-21 08:23:04.000000000 -0500 +@@ -84,7 +84,8 @@ + lprintf ("rtsp_plugin_read: %"PRId64" bytes ...\n", len); + + n = rtsp_session_read (this->rtsp, buf, len); +- this->curpos += n; ++ if (n > 0) ++ this->curpos += n; + + return n; + } +@@ -97,6 +98,11 @@ + + lprintf ("rtsp_plugin_read_block: %"PRId64" bytes...\n", todo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +@@ -123,10 +129,16 @@ + if ((origin == SEEK_CUR) && (offset >= 0)) { + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- this->curpos += rtsp_plugin_read (this_gen, this->scratch, BUFSIZE); ++ off_t n = rtsp_plugin_read (this_gen, this->scratch, BUFSIZE); ++ if (n <= 0) ++ return this->curpos; ++ this->curpos += n; + } + +- this->curpos += rtsp_plugin_read (this_gen, this->scratch, offset); ++ off_t n = rtsp_plugin_read (this_gen, this->scratch, offset); ++ if (n <= 0) ++ return this->curpos; ++ this->curpos += n; + } + + return this->curpos; +diff -urNad xine-lib-1.1.15~/src/input/input_smb.c xine-lib-1.1.15/src/input/input_smb.c +--- xine-lib-1.1.15~/src/input/input_smb.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_smb.c 2009-01-21 08:23:04.000000000 -0500 +@@ -69,6 +69,8 @@ + smb_input_t *this = (smb_input_t *) this_gen; + off_t n, num_bytes; + ++ if (len < 0) ++ return -1; + num_bytes = 0; + + while (num_bytes < len) +@@ -89,6 +91,11 @@ + off_t total_bytes; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +diff -urNad xine-lib-1.1.15~/src/input/input_stdin_fifo.c xine-lib-1.1.15/src/input/input_stdin_fifo.c +--- xine-lib-1.1.15~/src/input/input_stdin_fifo.c 2008-06-14 19:15:00.000000000 -0400 ++++ xine-lib-1.1.15/src/input/input_stdin_fifo.c 2009-01-21 08:23:04.000000000 -0500 +@@ -85,6 +85,8 @@ + off_t n, total; + + lprintf ("reading %"PRId64" bytes...\n", len); ++ if (len < 0) ++ return -1; + + total=0; + if (this->curpos < this->preview_size) { +@@ -121,6 +123,11 @@ + /* stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; */ + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + ++ if (todo < 0 || todo > buf->size) { ++ buf->free_buffer (buf); ++ return NULL; ++ } ++ + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + +@@ -146,7 +153,7 @@ + if ((origin == SEEK_CUR) && (offset >= 0)) { + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) ++ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) + return this->curpos; + } + +@@ -168,7 +175,7 @@ + offset -= this->curpos; + + for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) { +- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) ) ++ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 ) + return this->curpos; + } + +@@ -270,6 +277,8 @@ + + this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview, + MAX_PREVIEW_SIZE); ++ if (this->preview_size < 0) ++ this->preview_size = 0; + this->curpos = 0; + + return 1; only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/11_SECURITY_CVE-2008-5243.dpatch +++ xine-lib-1.1.15/debian/patches/11_SECURITY_CVE-2008-5243.dpatch @@ -0,0 +1,58 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 11_SECURITY_CVE-2008-5243.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix buffer indexing using untrusted or unchecked values. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=4982c9920f42657d0797145bf197127f18d8972c;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_real.c xine-lib-1.1.15/src/demuxers/demux_real.c +--- xine-lib-1.1.15~/src/demuxers/demux_real.c 2009-01-15 10:00:48.000000000 -0500 ++++ xine-lib-1.1.15/src/demuxers/demux_real.c 2009-01-15 10:00:52.000000000 -0500 +@@ -497,7 +497,8 @@ + 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 @@ + + 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); only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/04_SECURITY_cdda_server_overflow.dpatch +++ xine-lib-1.1.15/debian/patches/04_SECURITY_cdda_server_overflow.dpatch @@ -0,0 +1,36 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 04_SECURITY_cdda_server_overflow.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix integer overflow in the CDDA server. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=30eb014e9b320035de309ee442ebbff6d405987b;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/misc/cdda_server.c xine-lib-1.1.15/misc/cdda_server.c +--- xine-lib-1.1.15~/misc/cdda_server.c 2008-04-28 09:30:54.000000000 -0400 ++++ xine-lib-1.1.15/misc/cdda_server.c 2009-01-15 09:49:54.000000000 -0500 +@@ -480,6 +480,12 @@ + + sscanf(cmd,"%*s %d %d", &start_frame, &num_frames); + ++ if (num_frames > INT_MAX / CD_RAW_FRAME_SIZE) ++ { ++ printf ("fatal error: integer overflow\n"); ++ exit (1); ++ } ++ + n = num_frames * CD_RAW_FRAME_SIZE; + buf = malloc( n ); + if( !buf ) +@@ -556,6 +562,11 @@ + char *buf; + + sscanf(cmd,"%*s %d %d", &blocks, &flags); ++ if (blocks > INT_MAX / DVD_BLOCK_SIZE) ++ { ++ printf ("fatal error: integer overflow\n"); ++ exit (1); ++ } + + n = blocks * DVD_BLOCK_SIZE; + buf = malloc( n ); only in patch2: unchanged: --- xine-lib-1.1.15.orig/debian/patches/05_SECURITY_CVE-2008-5234.dpatch +++ xine-lib-1.1.15/debian/patches/05_SECURITY_CVE-2008-5234.dpatch @@ -0,0 +1,96 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 05_SECURITY_CVE-2008-5234.dpatch by Marc Deslauriers +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Description: fix heap overflow and unchecked malloc in Quicktime atom parsing. +## DP: Patch: http://hg.debian.org/hg/xine-lib/xine-lib?cmd=changeset;node=6e81eec36701;style=gitweb + +@DPATCH@ +diff -urNad xine-lib-1.1.15~/src/demuxers/demux_qt.c xine-lib-1.1.15/src/demuxers/demux_qt.c +--- xine-lib-1.1.15~/src/demuxers/demux_qt.c 2008-06-25 09:04:09.000000000 -0400 ++++ xine-lib-1.1.15/src/demuxers/demux_qt.c 2009-01-15 09:52:01.000000000 -0500 +@@ -738,6 +738,8 @@ + + if (current_atom == ART_ATOM) { + string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; ++ if (string_size <= 0) ++ continue; + info->artist = xine_xmalloc(string_size); + if (info->artist) { + strncpy(info->artist, &meta_atom[i + 20], string_size - 1); +@@ -745,6 +747,8 @@ + } + } else if (current_atom == NAM_ATOM) { + string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; ++ if (string_size <= 0) ++ continue; + info->name = xine_xmalloc(string_size); + if (info->name) { + strncpy(info->name, &meta_atom[i + 20], string_size - 1); +@@ -752,6 +756,8 @@ + } + } else if (current_atom == ALB_ATOM) { + string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; ++ if (string_size <= 0) ++ continue; + info->album = xine_xmalloc(string_size); + if (info->album) { + strncpy(info->album, &meta_atom[i + 20], string_size - 1); +@@ -759,6 +765,8 @@ + } + } else if (current_atom == GEN_ATOM) { + string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; ++ if (string_size <= 0) ++ continue; + info->genre = xine_xmalloc(string_size); + if (info->genre) { + strncpy(info->genre, &meta_atom[i + 20], string_size - 1); +@@ -766,6 +774,8 @@ + } + } else if (current_atom == TOO_ATOM) { + string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; ++ if (string_size <= 0) ++ continue; + info->comment = xine_xmalloc(string_size); + if (info->comment) { + strncpy(info->comment, &meta_atom[i + 20], string_size - 1); +@@ -773,6 +783,8 @@ + } + } else if (current_atom == WRT_ATOM) { + string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; ++ if (string_size <= 0) ++ continue; + info->composer = xine_xmalloc(string_size); + if (info->composer) { + strncpy(info->composer, &meta_atom[i + 20], string_size - 1); +@@ -780,6 +792,8 @@ + } + } else if (current_atom == DAY_ATOM) { + string_size = _X_BE_32(&meta_atom[i + 4]) - 16 + 1; ++ if (string_size <= 0) ++ continue; + info->year = xine_xmalloc(string_size); + if (info->year) { + strncpy(info->year, &meta_atom[i + 20], string_size - 1); +@@ -947,6 +961,10 @@ + + /* allocate space for each of the properties unions */ + trak->stsd_atoms_count = _X_BE_32(&trak_atom[i + 8]); ++ if (trak->stsd_atoms_count <= 0) { ++ last_error = QT_HEADER_TROUBLE; ++ goto free_trak; ++ } + trak->stsd_atoms = calloc(trak->stsd_atoms_count, sizeof(properties_t)); + if (!trak->stsd_atoms) { + last_error = QT_NO_MEMORY; +@@ -958,6 +976,10 @@ + for (k = 0; k < trak->stsd_atoms_count; k++) { + + current_stsd_atom_size = _X_BE_32(&trak_atom[atom_pos - 4]); ++ if (current_stsd_atom_size < 4) { ++ last_error = QT_HEADER_TROUBLE; ++ goto free_trak; ++ } + + if (trak->type == MEDIA_VIDEO) { +