[MPlayer-cvslog] CVS: main/libmpdemux demux_mov.c, 1.147, 1.148 demux_real.c, 1.96, 1.97
Roberto Togni CVS
syncmail at mplayerhq.hu
Thu May 11 20:50:49 CEST 2006
CVS change done by Roberto Togni CVS
Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var2/tmp/cvs-serv22262
Modified Files:
demux_mov.c demux_real.c
Log Message:
Fix potential integer overflows in memory allocation
Index: demux_mov.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_mov.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -r1.147 -r1.148
--- demux_mov.c 23 Apr 2006 11:38:06 -0000 1.147
+++ demux_mov.c 11 May 2006 18:50:46 -0000 1.148
@@ -145,6 +145,16 @@
void* desc; // image/sound/etc description (pointer to ImageDescription etc)
} mov_track_t;
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)-1)
+#endif
+
+void *realloc_struct(void *ptr, size_t nmemb, size_t size) {
+ if (nmemb > SIZE_MAX / size)
+ return NULL;
+ return realloc(ptr, nmemb * size);
+}
+
void mov_build_index(mov_track_t* trak,int timescale){
int i,j,s;
int last=trak->chunks_size;
@@ -206,7 +216,7 @@
// workaround for fixed-size video frames (dv and uncompressed)
if(!trak->samples_size && trak->type!=MOV_TRAK_AUDIO){
trak->samples_size=s;
- trak->samples=malloc(sizeof(mov_sample_t)*s);
+ trak->samples=calloc(s, sizeof(mov_sample_t));
for(i=0;i<s;i++)
trak->samples[i].size=trak->samplesize;
trak->samplesize=0;
@@ -225,7 +235,7 @@
"MOV: durmap or chunkmap bigger than sample count (%i vs %i)\n",
s, trak->samples_size);
trak->samples_size = s;
- trak->samples = realloc(trak->samples, sizeof(mov_sample_t) * s);
+ trak->samples = realloc_struct(trak->samples, s, sizeof(mov_sample_t));
}
// calc pts:
@@ -899,7 +909,7 @@
// 82 char[4] atom type
// 86 ... atom data
- { ImageDescription* id=malloc(8+trak->stdata_len);
+ { ImageDescription* id=malloc(8+trak->stdata_len); // safe
trak->desc=id;
id->idSize=8+trak->stdata_len;
// id->cType=bswap_32(trak->fourcc);
@@ -1145,6 +1155,10 @@
else
{
if (trak->fourcc == mmioFOURCC('a','v','c','1')) {
+ if (trak->stream_header_len > 0xffffffff - sizeof(BITMAPINFOHEADER)) {
+ mp_msg(MSGT_DEMUXER, MSGL_ERR, "Invalid extradata size %d, skipping\n");
+ trak->stream_header_len = 0;
+ }
sh->bih=malloc(sizeof(BITMAPINFOHEADER) + trak->stream_header_len);
memset(sh->bih,0,sizeof(BITMAPINFOHEADER) + trak->stream_header_len);
sh->bih->biSize=40 + trak->stream_header_len;
@@ -1258,12 +1272,18 @@
// int temp=stream_read_dword(demuxer->stream);
unsigned int moov_sz=stream_read_dword(demuxer->stream);
unsigned int cmov_sz=len-4;
- unsigned char* cmov_buf=malloc(cmov_sz);
- unsigned char* moov_buf=malloc(moov_sz+16);
+ unsigned char* cmov_buf;
+ unsigned char* moov_buf;
int zret;
z_stream zstrm;
stream_t* backup;
+ if (moov_sz > 0xffffffff - 16) {
+ mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid cmvd atom size %d\n", moov_sz);
+ break;
+ }
+ cmov_buf=malloc(cmov_sz);
+ moov_buf=malloc(moov_sz+16);
mp_msg(MSGT_DEMUX, MSGL_V, "Compressed header size: %d / %d\n",cmov_sz,moov_sz);
stream_read(demuxer->stream,cmov_buf,cmov_sz);
@@ -1582,8 +1602,7 @@
mp_msg(MSGT_DEMUX, MSGL_V,
"MOV: %*sSample duration table! (%d blocks)\n", level, "",
len);
- trak->durmap = malloc(sizeof(mov_durmap_t) * len);
- memset(trak->durmap, 0, sizeof(mov_durmap_t) * len);
+ trak->durmap = calloc(len, sizeof(mov_durmap_t));
trak->durmap_size = len;
for (i = 0; i < len; i++) {
trak->durmap[i].num = stream_read_dword(demuxer->stream);
@@ -1606,7 +1625,7 @@
len, ver, flags);
// read data:
trak->chunkmap_size = len;
- trak->chunkmap = malloc(sizeof(mov_chunkmap_t) * len);
+ trak->chunkmap = calloc(len, sizeof(mov_chunkmap_t));
for (i = 0; i < len; i++) {
trak->chunkmap[i].first = stream_read_dword(demuxer->stream) - 1;
trak->chunkmap[i].spc = stream_read_dword(demuxer->stream);
@@ -1627,7 +1646,7 @@
trak->samplesize = ss;
if (!ss) {
// variable samplesize
- trak->samples = realloc(trak->samples,sizeof(mov_sample_t)*entries);
+ trak->samples = realloc_struct(trak->samples, entries, sizeof(mov_sample_t));
trak->samples_size = entries;
for (i = 0; i < entries; i++)
trak->samples[i].size = stream_read_dword(demuxer->stream);
@@ -1643,7 +1662,7 @@
len);
// extend array if needed:
if (len > trak->chunks_size) {
- trak->chunks = realloc(trak->chunks, sizeof(mov_chunk_t) * len);
+ trak->chunks = realloc_struct(trak->chunks, len, sizeof(mov_chunk_t));
trak->chunks_size = len;
}
// read elements:
@@ -1660,7 +1679,7 @@
len);
// extend array if needed:
if (len > trak->chunks_size) {
- trak->chunks = realloc(trak->chunks, sizeof(mov_chunk_t) * len);
+ trak->chunks = realloc_struct(trak->chunks, len, sizeof(mov_chunk_t));
trak->chunks_size = len;
}
// read elements:
@@ -1685,7 +1704,7 @@
"MOV: %*sSyncing samples (keyframes) table! (%d entries) (ver:%d,flags:%d)\n", level, "",
entries, ver, flags);
trak->keyframes_size = entries;
- trak->keyframes = malloc(sizeof(unsigned int) * entries);
+ trak->keyframes = calloc(entries, sizeof(unsigned int));
for (i = 0; i < entries; i++)
trak->keyframes[i] = stream_read_dword(demuxer->stream) - 1;
break;
@@ -1721,7 +1740,7 @@
entries, ver, flags);
#if 1
trak->editlist_size = entries;
- trak->editlist = malloc(trak->editlist_size * sizeof(mov_editlist_t));
+ trak->editlist = calloc(trak->editlist_size, sizeof(mov_editlist_t));
for (i = 0; i < entries; i++) {
int dur = stream_read_dword(demuxer->stream);
int mt = stream_read_dword(demuxer->stream);
Index: demux_real.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_real.c,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -r1.96 -r1.97
--- demux_real.c 22 Apr 2006 05:12:10 -0000 1.96
+++ demux_real.c 11 May 2006 18:50:46 -0000 1.97
@@ -122,6 +122,9 @@
int audio_filepos; ///< file position of first audio packet in block
} real_priv_t;
+//! use at most 200 MB of memory for index, corresponds to around 25 million entries
+#define MAX_INDEX_ENTRIES (200*1024*1024 / sizeof(real_index_table_t))
+
/* originally from FFmpeg */
static void get_str(int isbyte, demuxer_t *demuxer, char *buf, int buf_size)
{
@@ -222,7 +225,7 @@
next_header_pos = stream_read_dword(demuxer->stream);
mp_msg(MSGT_DEMUX, MSGL_V,"next_header_pos: %d\n", next_header_pos);
- if (entries <= 0)
+ if (entries <= 0 || entries > MAX_INDEX_ENTRIES)
{
if (next_header_pos)
goto read_index;
@@ -231,7 +234,7 @@
}
priv->index_table_size[stream_id] = entries;
- priv->index_table[stream_id] = malloc(priv->index_table_size[stream_id] * sizeof(real_index_table_t));
+ priv->index_table[stream_id] = calloc(priv->index_table_size[stream_id], sizeof(real_index_table_t));
for (i = 0; i < entries; i++)
{
@@ -267,6 +270,10 @@
{
real_priv_t *priv = demuxer->priv;
real_index_table_t *index;
+ if (priv->index_table_size[stream_id] >= MAX_INDEX_ENTRIES) {
+ mp_msg(MSGT_DEMUXER, MSGL_WARN, "Index too large during building\n");
+ return;
+ }
if (priv->index_table_size[stream_id] >= priv->index_malloc_size[stream_id])
{
if (priv->index_malloc_size[stream_id] == 0)
More information about the MPlayer-cvslog
mailing list