diff -u mplayer-0.99+1.0pre8/debian/changelog mplayer-0.99+1.0pre8/debian/changelog --- mplayer-0.99+1.0pre8/debian/changelog +++ mplayer-0.99+1.0pre8/debian/changelog @@ -1,3 +1,20 @@ +mplayer (2:0.99+1.0pre8-0ubuntu8.3) edgy-security; urgency=low + + * SECURITY UPDATE: buffer overruns in RMMF, CDDB, MOV demuxer, FLAC header + parser, and URL parser. (LP: #191488) + * stream/librtsp/rtsp_session.c, stream/realrtsp/rmff.c, + stream/realrtsp/rmff.h, libmpdemux/demux_mov.c, libmpdemux/demux_audio.c, + stream/stream_cddb.c, stream/url.c: Patches from upstream. + * References: + - CVE-2008-0225 + - CVE-2008-0238 + - CVE-2008-0485 + - CVE-2008-0486 + - CVE-2008-0629 + - CVE-2008-0630 + + -- William Grant Sat, 09 Mar 2008 10:50:06 +1100 + mplayer (2:0.99+1.0pre8-0ubuntu8.2) edgy-security; urgency=low * SECURITY UPDATE: buffer overruns in CDDB (LP: #118855), DMO decoder diff -u mplayer-0.99+1.0pre8/libmpdemux/cddb.c mplayer-0.99+1.0pre8/libmpdemux/cddb.c --- mplayer-0.99+1.0pre8/libmpdemux/cddb.c +++ mplayer-0.99+1.0pre8/libmpdemux/cddb.c @@ -56,6 +56,9 @@ #include "stream.h" #include "network.h" +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) + #define DEFAULT_FREEDB_SERVER "freedb.freedb.org" #define DEFAULT_CACHE_DIR "/.cddb/" @@ -513,8 +516,9 @@ } else { len = ptr2-ptr+1; } + len = FFMIN(sizeof(album_title) - 1, len); strncpy(album_title, ptr, len); - album_title[len-2]='\0'; + album_title[len]='\0'; } mp_msg(MSGT_DEMUX, MSGL_STATUS, MSGTR_MPDEMUX_CDDB_ParseOKFoundAlbumTitle, album_title); return 0; @@ -550,8 +554,9 @@ } else { len = ptr2-ptr+1; } + len = FFMIN(sizeof(album_title) - 1, len); strncpy(album_title, ptr, len); - album_title[len-2]='\0'; + album_title[len]='\0'; } mp_msg(MSGT_DEMUX, MSGL_STATUS, MSGTR_MPDEMUX_CDDB_ParseOKFoundAlbumTitle, album_title); return cddb_request_titles(cddb_data); only in patch2: unchanged: --- mplayer-0.99+1.0pre8.orig/libmpdemux/realrtsp/rmff.c +++ mplayer-0.99+1.0pre8/libmpdemux/realrtsp/rmff.c @@ -28,6 +28,7 @@ #include "rmff.h" #include "xbuffer.h" +#include "mp_msg.h" /* #define LOG @@ -74,9 +75,13 @@ * writes header data to a buffer */ -static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) { +static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer, int bufsize) { + + if (!fileheader) return 0; + + if (bufsize < RMFF_FILEHEADER_SIZE) + return -1; - if (!fileheader) return; fileheader->object_id=BE_32(&fileheader->object_id); fileheader->size=BE_32(&fileheader->size); fileheader->object_version=BE_16(&fileheader->object_version); @@ -92,11 +97,17 @@ fileheader->file_version=BE_32(&fileheader->file_version); fileheader->num_headers=BE_32(&fileheader->num_headers); fileheader->object_id=BE_32(&fileheader->object_id); + + return RMFF_FILEHEADER_SIZE; } -static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) { +static int rmff_dump_prop(rmff_prop_t *prop, char *buffer, int bufsize) { + + if (!prop) return 0; + + if (bufsize < RMFF_PROPHEADER_SIZE) + return -1; - if (!prop) return; prop->object_id=BE_32(&prop->object_id); prop->size=BE_32(&prop->size); prop->object_version=BE_16(&prop->object_version); @@ -132,13 +143,20 @@ prop->num_streams=BE_16(&prop->num_streams); prop->flags=BE_16(&prop->flags); prop->object_id=BE_32(&prop->object_id); + + return RMFF_PROPHEADER_SIZE; } -static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) { +static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer, int bufsize) { int s1, s2, s3; - if (!mdpr) return; + if (!mdpr) return 0; + + if (!(bufsize > RMFF_MDPRHEADER_SIZE + mdpr->stream_name_size + mdpr->mime_type_size && + (unsigned)bufsize - RMFF_MDPRHEADER_SIZE - mdpr->stream_name_size - mdpr->mime_type_size > mdpr->type_specific_len)) + return -1; + mdpr->object_id=BE_32(&mdpr->object_id); mdpr->size=BE_32(&mdpr->size); mdpr->object_version=BE_16(&mdpr->object_version); @@ -180,13 +198,19 @@ mdpr->duration=BE_32(&mdpr->duration); mdpr->object_id=BE_32(&mdpr->object_id); + return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3; } -static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) { +static int rmff_dump_cont(rmff_cont_t *cont, char *buffer, int bufsize) { int p; - if (!cont) return; + if (!cont) return 0; + + if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + + cont->copyright_len + cont->comment_len) + return -1; + cont->object_id=BE_32(&cont->object_id); cont->size=BE_32(&cont->size); cont->object_version=BE_16(&cont->object_version); @@ -220,11 +244,18 @@ cont->size=BE_32(&cont->size); cont->object_version=BE_16(&cont->object_version); cont->object_id=BE_32(&cont->object_id); + + return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + + cont->copyright_len + cont->comment_len; } -static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) { +static int rmff_dump_dataheader(rmff_data_t *data, char *buffer, int bufsize) { + + if (!data) return 0; + + if (bufsize < RMFF_DATAHEADER_SIZE) + return -1; - if (!data) return; data->object_id=BE_32(&data->object_id); data->size=BE_32(&data->size); data->object_version=BE_16(&data->object_version); @@ -240,33 +271,48 @@ data->size=BE_32(&data->size); data->object_version=BE_16(&data->object_version); data->object_id=BE_32(&data->object_id); + + return RMFF_DATAHEADER_SIZE; } int rmff_dump_header(rmff_header_t *h, char *buffer, int max) { - int written=0; + int written=0, size; rmff_mdpr_t **stream=h->streams; - rmff_dump_fileheader(h->fileheader, &buffer[written]); - written+=h->fileheader->size; - rmff_dump_prop(h->prop, &buffer[written]); - written+=h->prop->size; - rmff_dump_cont(h->cont, &buffer[written]); - written+=h->cont->size; + if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; + if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; + if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; if (stream) { while(*stream) { - rmff_dump_mdpr(*stream, &buffer[written]); - written+=(*stream)->size; + if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; stream++; } } - rmff_dump_dataheader(h->data, &buffer[written]); - written+=18; + if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; return written; + +buftoosmall: + mp_msg(MSGT_STREAM, MSGL_ERR, "rmff_dumpheader: buffer too small, aborting. Please report\n"); + return -1; } void rmff_dump_pheader(rmff_pheader_t *h, char *data) { only in patch2: unchanged: --- mplayer-0.99+1.0pre8.orig/libmpdemux/realrtsp/rmff.h +++ mplayer-0.99+1.0pre8/libmpdemux/realrtsp/rmff.h @@ -49,6 +49,12 @@ #define RMFF_HEADER_SIZE 0x12 +#define RMFF_FILEHEADER_SIZE 18 +#define RMFF_PROPHEADER_SIZE 50 +#define RMFF_MDPRHEADER_SIZE 46 +#define RMFF_CONTHEADER_SIZE 18 +#define RMFF_DATAHEADER_SIZE 18 + #define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \ (((long)(unsigned char)(ch3) ) | \ ( (long)(unsigned char)(ch2) << 8 ) | \ only in patch2: unchanged: --- mplayer-0.99+1.0pre8.orig/libmpdemux/realrtsp/rtsp_session.c +++ mplayer-0.99+1.0pre8/libmpdemux/realrtsp/rtsp_session.c @@ -134,7 +134,17 @@ } } - rtsp_session->header_len=rmff_dump_header(h,rtsp_session->header,1024); + rtsp_session->header_len=rmff_dump_header(h,rtsp_session->header,HEADER_SIZE); + + if (rtsp_session->header_len < 0) { + printf("rtsp_session: error while dumping RMFF headers, session can not be established.\n"); + rtsp_close(rtsp_session->s); + free (server); + free (mrl_line); + rtsp_session->recv = xbuffer_free(rtsp_session->recv); + free(rtsp_session); + return NULL; + } rtsp_session->recv = xbuffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len); rtsp_session->recv_size = rtsp_session->header_len; only in patch2: unchanged: --- mplayer-0.99+1.0pre8.orig/libmpdemux/demux_audio.c +++ mplayer-0.99+1.0pre8/libmpdemux/demux_audio.c @@ -235,6 +235,8 @@ ptr += 4; comment = (char *) ptr; + if (&comment[length] < comments || &comment[length] >= &comments[blk_len]) + return; c = comment[length]; comment[length] = 0; only in patch2: unchanged: --- mplayer-0.99+1.0pre8.orig/libmpdemux/demux_mov.c +++ mplayer-0.99+1.0pre8/libmpdemux/demux_mov.c @@ -51,6 +51,9 @@ #include #endif +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) + #define BE_16(x) (((unsigned char *)(x))[0] << 8 | \ ((unsigned char *)(x))[1]) #define BE_32(x) (((unsigned char *)(x))[0] << 24 | \ @@ -171,11 +174,12 @@ i=trak->chunkmap_size; while(i>0){ --i; - for(j=trak->chunkmap[i].first;jchunkmap[i].first, 0); + for(;jchunks[j].desc=trak->chunkmap[i].sdid; trak->chunks[j].size=trak->chunkmap[i].spc; } - last=trak->chunkmap[i].first; + last=FFMIN(trak->chunkmap[i].first, trak->chunks_size); } #if 0 @@ -233,6 +237,8 @@ s=0; for(j=0;jdurmap_size;j++){ for(i=0;idurmap[j].num;i++){ + if (s >= trak->samples_size) + break; trak->samples[s].pts=pts; ++s; pts+=trak->durmap[j].dur; @@ -244,6 +250,8 @@ for(j=0;jchunks_size;j++){ off_t pos=trak->chunks[j].pos; for(i=0;ichunks[j].size;i++){ + if (s >= trak->samples_size) + break; trak->samples[s].pos=pos; mp_msg(MSGT_DEMUX, MSGL_DBG3, "Sample %5d: pts=%8d off=0x%08X size=%d\n",s, trak->samples[s].pts, @@ -1484,8 +1492,7 @@ if( udta_len>udta_size) udta_len=udta_size; { - char dump[udta_len-4]; - stream_read(demuxer->stream, (char *)&dump, udta_len-4-4); + stream_skip(demuxer->stream, udta_len-4-4); udta_size -= udta_len; } } only in patch2: unchanged: --- mplayer-0.99+1.0pre8.orig/libmpdemux/url.c +++ mplayer-0.99+1.0pre8/libmpdemux/url.c @@ -304,6 +304,7 @@ } } + tmp = NULL; while(i < len) { // look for the next char that must be kept for (j=i;j