changeset 2422:18b8b2dcc037 libavcodec

various security fixes and precautionary checks
author michael
date Wed, 12 Jan 2005 00:16:25 +0000
parents e326490f58c4
children 87b7fbed8609
files 4xm.c asv1.c avcodec.h dv.c ffv1.c flicvideo.c h263.c h263dec.c h264.c huffyuv.c imgconvert.c imgresample.c indeo3.c mem.c mjpeg.c mpegvideo.c mpegvideo.h png.c pnm.c ratecontrol.c snow.c svq1.c utils.c vp3.c vqavideo.c xan.c
diffstat 26 files changed, 285 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/4xm.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/4xm.c	Wed Jan 12 00:16:25 2005 +0000
@@ -323,13 +323,19 @@
     uint16_t *src= (uint16_t*)f->last_picture.data[0];
     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
     const int stride= f->current_picture.linesize[0]>>1;
-    const int bitstream_size= get32(buf+8);
-    const int bytestream_size= get32(buf+16);
-    const int wordstream_size= get32(buf+12);
+    const unsigned int bitstream_size= get32(buf+8);
+    const unsigned int bytestream_size= get32(buf+16);
+    const unsigned int wordstream_size= get32(buf+12);
     
-    if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length)
+    if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length
+       || bitstream_size  > (1<<26)
+       || bytestream_size > (1<<26)
+       || wordstream_size > (1<<26)
+       ){
         av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, 
         bitstream_size+ bytestream_size+ wordstream_size - length);
+        return -1;
+    }
     
     f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
     f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)(buf + 20), bitstream_size/4);
@@ -550,13 +556,17 @@
     const int height= f->avctx->height;
     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
     const int stride= f->current_picture.linesize[0]>>1;
-    const int bitstream_size= get32(buf);
+    const unsigned int bitstream_size= get32(buf);
     const int token_count __attribute__((unused)) = get32(buf + bitstream_size + 8);
-    int prestream_size= 4*get32(buf + bitstream_size + 4);
+    unsigned int prestream_size= 4*get32(buf + bitstream_size + 4);
     uint8_t *prestream= buf + bitstream_size + 12;
     
-    if(prestream_size + bitstream_size + 12 != length)
+    if(prestream_size + bitstream_size + 12 != length
+       || bitstream_size > (1<<26)
+       || prestream_size > (1<<26)){
         av_log(f->avctx, AV_LOG_ERROR, "size missmatch %d %d %d\n", prestream_size, bitstream_size, length);
+        return -1;
+    }
    
     prestream= read_huffman_tables(f, prestream);
 
--- a/asv1.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/asv1.c	Wed Jan 12 00:16:25 2005 +0000
@@ -339,8 +339,13 @@
     return 0;
 }
 
-static inline void encode_mb(ASV1Context *a, DCTELEM block[6][64]){
+static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){
     int i;
+    
+    if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){
+        av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+        return -1;
+    }
 
     if(a->avctx->codec_id == CODEC_ID_ASV1){
         for(i=0; i<6; i++)
@@ -349,6 +354,7 @@
         for(i=0; i<6; i++)
             asv2_encode_block(a, block[i]);
     }
+    return 0;
 }
 
 static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){
--- a/avcodec.h	Tue Jan 11 08:16:04 2005 +0000
+++ b/avcodec.h	Wed Jan 12 00:16:25 2005 +0000
@@ -17,7 +17,7 @@
 
 #define FFMPEG_VERSION_INT     0x000409
 #define FFMPEG_VERSION         "0.4.9-pre1"
-#define LIBAVCODEC_BUILD       4736
+#define LIBAVCODEC_BUILD       4737
 
 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVCODEC_VERSION     FFMPEG_VERSION
@@ -235,6 +235,12 @@
  */
 #define FF_INPUT_BUFFER_PADDING_SIZE 8
 
+/**
+ * minimum encoding buffer size.
+ * used to avoid some checks during header writing
+ */
+#define FF_MIN_BUFFER_SIZE 16384
+
 /* motion estimation type, EPZS by default */
 enum Motion_Est_ID {
     ME_ZERO = 1,
@@ -2112,6 +2118,7 @@
 void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
 int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
 void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
+int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h);
 enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt);
 
 int avcodec_thread_init(AVCodecContext *s, int thread_count);
--- a/dv.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/dv.c	Wed Jan 12 00:16:25 2005 +0000
@@ -931,7 +931,9 @@
     s->sys = dv_codec_profile(c);
     if (!s->sys)
 	return -1;
-    
+    if(buf_size < s->sys->frame_size)
+        return -1;
+
     c->pix_fmt = s->sys->pix_fmt;
     s->picture = *((AVFrame *)data);
 
--- a/ffv1.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/ffv1.c	Wed Jan 12 00:16:25 2005 +0000
@@ -354,7 +354,7 @@
     return ret;
 }
 
-static inline void encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
+static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
     PlaneContext * const p= &s->plane[plane_index];
     RangeCoder * const c= &s->c;
     int x;
@@ -362,6 +362,18 @@
     int run_count=0;
     int run_mode=0;
 
+    if(s->ac){
+        if(c->bytestream_end - c->bytestream < w*20){
+            av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+            return -1;
+        }
+    }else{
+        if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < w*4){
+            av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+            return -1;
+        }
+    }
+
     for(x=0; x<w; x++){
         int diff, context;
         
@@ -416,6 +428,8 @@
             put_bits(&s->pb, 1, 1);
     }
     s->run_index= run_index;
+    
+    return 0;
 }
 
 static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){
@@ -896,7 +910,7 @@
     context_count=1;
     for(i=0; i<5; i++){
         context_count*= read_quant_table(c, f->quant_table[i], context_count);
-        if(context_count < 0){
+        if(context_count < 0 || context_count > 32768){
             av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
             return -1;
         }
--- a/flicvideo.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/flicvideo.c	Wed Jan 12 00:16:25 2005 +0000
@@ -176,7 +176,7 @@
                 for (j = 0; j < color_changes; j++) {
 
                     /* wrap around, for good measure */
-                    if (palette_ptr >= 256)
+                    if ((unsigned)palette_ptr >= 256)
                         palette_ptr = 0;
 
                     r = buf[stream_ptr++] << color_shift;
--- a/h263.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/h263.c	Wed Jan 12 00:16:25 2005 +0000
@@ -6115,7 +6115,7 @@
         width = height = 0;
         break;
     }
-    if ((width == 0) || (height == 0))
+    if(avcodec_check_dimensions(s->avctx, width, height))
         return -1;
     s->width = width;
     s->height = height;
--- a/h263dec.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/h263dec.c	Wed Jan 12 00:16:25 2005 +0000
@@ -724,9 +724,8 @@
     if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_packed){
         int current_pos= get_bits_count(&s->gb)>>3;
         int startcode_found=0;
-
-        if(   buf_size - current_pos > 5 
-           && buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
+        
+        if(buf_size - current_pos > 5){
             int i;
             for(i=current_pos; i<buf_size-3; i++){
                 if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
@@ -741,6 +740,10 @@
         }
 
         if(startcode_found){
+            s->bitstream_buffer= av_fast_realloc(
+                s->bitstream_buffer, 
+                &s->allocated_bitstream_buffer_size, 
+                buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE);
             memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos);
             s->bitstream_buffer_size= buf_size - current_pos;
         }
--- a/h264.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/h264.c	Wed Jan 12 00:16:25 2005 +0000
@@ -5862,6 +5862,10 @@
     sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);
     sps->mb_width= get_ue_golomb(&s->gb) + 1;
     sps->mb_height= get_ue_golomb(&s->gb) + 1;
+    if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 || 
+       avcodec_check_dimensions(NULL, 16*sps->mb_width, 16*sps->mb_height))
+        return -1;
+
     sps->frame_mbs_only_flag= get_bits1(&s->gb);
     if(!sps->frame_mbs_only_flag)
         sps->mb_aff= get_bits1(&s->gb);
--- a/huffyuv.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/huffyuv.c	Wed Jan 12 00:16:25 2005 +0000
@@ -65,13 +65,14 @@
     int context;
     int picture_number;
     int last_slice_end;
-    uint8_t __align8 temp[3][2560];
+    uint8_t *temp[3];
     uint64_t stats[3][256];
     uint8_t len[3][256];
     uint32_t bits[3][256];
     VLC vlc[3];
     AVFrame picture;
-    uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
+    uint8_t *bitstream_buffer;
+    int bitstream_buffer_size;
     DSPContext dsp; 
 }HYuvContext;
 
@@ -347,24 +348,36 @@
 #endif
 }
 
-static int decode_init(AVCodecContext *avctx)
-{
+static int common_init(AVCodecContext *avctx){
     HYuvContext *s = avctx->priv_data;
-    int width, height;
+    int i;
 
     s->avctx= avctx;
     s->flags= avctx->flags;
         
     dsputil_init(&s->dsp, avctx);
+    
+    s->width= avctx->width;
+    s->height= avctx->height;
+    assert(s->width>0 && s->height>0);
+    
+    for(i=0; i<3; i++){
+        s->temp[i]= av_malloc(avctx->width + 16);
+    }
+    return 0;
+}
+
+static int decode_init(AVCodecContext *avctx)
+{
+    HYuvContext *s = avctx->priv_data;
+
+    common_init(avctx);
     memset(s->vlc, 0, 3*sizeof(VLC));
     
-    width= s->width= avctx->width;
-    height= s->height= avctx->height;
     avctx->coded_frame= &s->picture;
-    s->interlaced= height > 288;
+    s->interlaced= s->height > 288;
 
 s->bgr32=1;
-    assert(width && height);
 //if(avctx->extradata)
 //  printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
     if(avctx->extradata_size){
@@ -474,20 +487,12 @@
 static int encode_init(AVCodecContext *avctx)
 {
     HYuvContext *s = avctx->priv_data;
-    int i, j, width, height;
+    int i, j;
 
-    s->avctx= avctx;
-    s->flags= avctx->flags;
-        
-    dsputil_init(&s->dsp, avctx);
+    common_init(avctx);
     
-    width= s->width= avctx->width;
-    height= s->height= avctx->height;
-    
-    assert(width && height);
-    
-    avctx->extradata= av_mallocz(1024*30);
-    avctx->stats_out= av_mallocz(1024*30);
+    avctx->extradata= av_mallocz(1024*30); // 256*3+4 == 772
+    avctx->stats_out= av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
     s->version=2;
     
     avctx->coded_frame= &s->picture;
@@ -524,7 +529,7 @@
             av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported by huffyuv; use vcodec=ffvhuff\n");
             return -1;
         }
-        if(s->interlaced != ( height > 288 ))
+        if(s->interlaced != ( s->height > 288 ))
             av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n");
     }else if(avctx->strict_std_compliance>=0){
         av_log(avctx, AV_LOG_ERROR, "This codec is under development; files encoded with it may not be decodeable with future versions!!! Set vstrict=-1 to use it anyway.\n");
@@ -580,7 +585,7 @@
 
     if(s->context){
         for(i=0; i<3; i++){
-            int pels = width*height / (i?40:10);
+            int pels = s->width*s->height / (i?40:10);
             for(j=0; j<256; j++){
                 int d= FFMIN(j, 256-j);
                 s->stats[i][j]= pels/(d+1);
@@ -623,9 +628,14 @@
     }
 }
 
-static void encode_422_bitstream(HYuvContext *s, int count){
+static int encode_422_bitstream(HYuvContext *s, int count){
     int i;
     
+    if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 2*4*count){
+        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+        return -1;
+    }
+    
     count/=2;
     if(s->flags&CODEC_FLAG_PASS1){
         for(i=0; i<count; i++){
@@ -653,11 +663,17 @@
             put_bits(&s->pb, s->len[2][ s->temp[2][  i  ] ], s->bits[2][ s->temp[2][  i  ] ]);
         }
     }
+    return 0;
 }
 
-static void encode_gray_bitstream(HYuvContext *s, int count){
+static int encode_gray_bitstream(HYuvContext *s, int count){
     int i;
     
+    if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*count){
+        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+        return -1;
+    }
+
     count/=2;
     if(s->flags&CODEC_FLAG_PASS1){
         for(i=0; i<count; i++){
@@ -677,6 +693,7 @@
             put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
         }
     }
+    return 0;
 }
 
 static void decode_bgr_bitstream(HYuvContext *s, int count){
@@ -756,6 +773,8 @@
     /* no supplementary picture */
     if (buf_size == 0)
         return 0;
+        
+    s->bitstream_buffer= av_fast_realloc(s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
 
     s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
     
@@ -981,11 +1000,23 @@
     return (get_bits_count(&s->gb)+31)/32*4;
 }
 
+static int common_end(HYuvContext *s){
+    int i;
+    
+    for(i=0; i<3; i++){
+        av_freep(&s->temp[i]);
+    }
+    return 0;
+}
+
 static int decode_end(AVCodecContext *avctx)
 {
     HYuvContext *s = avctx->priv_data;
     int i;
     
+    common_end(s);
+    av_freep(&s->bitstream_buffer);
+    
     for(i=0; i<3; i++){
         free_vlc(&s->vlc[i]);
     }
@@ -1161,7 +1192,9 @@
 
 static int encode_end(AVCodecContext *avctx)
 {
-//    HYuvContext *s = avctx->priv_data;
+    HYuvContext *s = avctx->priv_data;
+    
+    common_end(s);
 
     av_freep(&avctx->extradata);
     av_freep(&avctx->stats_out);
--- a/imgconvert.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/imgconvert.c	Wed Jan 12 00:16:25 2005 +0000
@@ -268,6 +268,9 @@
     int size, w2, h2, size2;
     PixFmtInfo *pinfo;
     
+    if(avcodec_check_dimensions(NULL, width, height))
+        goto fail;
+
     pinfo = &pix_fmt_info[pix_fmt];
     size = width * height;
     switch(pix_fmt) {
@@ -344,6 +347,7 @@
         picture->linesize[1] = 4;
         return size2 + 256 * 4;
     default:
+fail:
         picture->data[0] = NULL;
         picture->data[1] = NULL;
         picture->data[2] = NULL;
@@ -360,7 +364,7 @@
     const unsigned char* s; 
     int size = avpicture_get_size(pix_fmt, width, height);
 
-    if (size > dest_size)
+    if (size > dest_size || size < 0)
         return -1;
 
     if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
@@ -1920,6 +1924,8 @@
     void *ptr;
 
     size = avpicture_get_size(pix_fmt, width, height);
+    if(size<0)
+        goto fail;
     ptr = av_malloc(size);
     if (!ptr)
         goto fail;
--- a/imgresample.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/imgresample.c	Wed Jan 12 00:16:25 2005 +0000
@@ -561,6 +561,8 @@
     s = av_mallocz(sizeof(ImgReSampleContext));
     if (!s)
         return NULL;
+    if((unsigned)owidth >= UINT_MAX / (LINE_BUF_HEIGHT + NB_TAPS))
+        return NULL;
     s->line_buf = av_mallocz(owidth * (LINE_BUF_HEIGHT + NB_TAPS));
     if (!s->line_buf) 
         goto fail;
--- a/indeo3.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/indeo3.c	Wed Jan 12 00:16:25 2005 +0000
@@ -196,6 +196,10 @@
   hdr_height = le2me_16(*(uint16_t *)buf_pos);
   buf_pos += 2;
   hdr_width = le2me_16(*(uint16_t *)buf_pos);
+  
+  if(avcodec_check_dimensions(NULL, hdr_width, hdr_height))
+      return -1;
+  
   buf_pos += 2;
   chroma_height = ((hdr_height >> 2) + 3) & 0x7ffc;
   chroma_width = ((hdr_width >> 2) + 3) & 0x7ffc;
--- a/mem.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/mem.c	Wed Jan 12 00:16:25 2005 +0000
@@ -45,6 +45,10 @@
 void *av_malloc(unsigned int size)
 {
     void *ptr;
+
+    /* lets disallow possible ambiguous cases */
+    if(size > INT_MAX)
+        return NULL;
     
 #ifdef MEMALIGN_HACK
     int diff;
@@ -93,6 +97,10 @@
  */
 void *av_realloc(void *ptr, unsigned int size)
 {
+    /* lets disallow possible ambiguous cases */
+    if(size > INT_MAX)
+        return NULL;
+
 #ifdef MEMALIGN_HACK
     //FIXME this isnt aligned correctly though it probably isnt needed
     int diff;
--- a/mjpeg.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/mjpeg.c	Wed Jan 12 00:16:25 2005 +0000
@@ -659,11 +659,11 @@
     mjpeg_picture_header(s);
 
     s->header_bits= put_bits_count(&s->pb);
-
+    
     if(avctx->pix_fmt == PIX_FMT_RGBA32){
         int x, y, i;
         const int linesize= p->linesize[0];
-        uint16_t buffer[2048][4];
+        uint16_t (*buffer)[4]= s->rd_scratchpad;
         int left[3], top[3], topleft[3];
 
         for(i=0; i<3; i++){
@@ -674,6 +674,11 @@
             const int modified_predictor= y ? predictor : 1;
             uint8_t *ptr = p->data[0] + (linesize * y);
 
+            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){
+                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                return -1;
+            }
+            
             for(i=0; i<3; i++){
                 top[i]= left[i]= topleft[i]= buffer[0][i];
             }
@@ -707,6 +712,10 @@
         const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0];
         
         for(mb_y = 0; mb_y < mb_height; mb_y++) {
+            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){
+                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                return -1;
+            }
             for(mb_x = 0; mb_x < mb_width; mb_x++) {
                 if(mb_x==0 || mb_y==0){
                     for(i=0;i<3;i++) {
@@ -1060,7 +1069,10 @@
     }
     height = get_bits(&s->gb, 16);
     width = get_bits(&s->gb, 16);
+    
     dprintf("sof0: picture: %dx%d\n", width, height);
+    if(avcodec_check_dimensions(s->avctx, width, height))
+        return -1;
 
     nb_components = get_bits(&s->gb, 8);
     if (nb_components <= 0 ||
@@ -1228,11 +1240,14 @@
 
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point_transform){
     int i, mb_x, mb_y;
-    uint16_t buffer[2048][4];
+    uint16_t buffer[32768][4];
     int left[3], top[3], topleft[3];
     const int linesize= s->linesize[0];
     const int mask= (1<<s->bits)-1;
     
+    if((unsigned)s->mb_width > 32768) //dynamic alloc
+        return -1;
+    
     for(i=0; i<3; i++){
         buffer[0][i]= 1 << (s->bits + point_transform - 1);
     }
--- a/mpegvideo.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/mpegvideo.c	Wed Jan 12 00:16:25 2005 +0000
@@ -619,6 +619,9 @@
         return -1;
     }
 
+    if((s->width || s->height) && avcodec_check_dimensions(s->avctx, s->width, s->height))
+        return -1;
+
     dsputil_init(&s->dsp, s->avctx);
     DCT_common_init(s);
 
@@ -742,9 +745,6 @@
         CHECKED_ALLOCZ(s->coded_block_base, y_size);
         s->coded_block= s->coded_block_base + s->b8_stride + 1;
         
-        /* divx501 bitstream reorder buffer */
-        CHECKED_ALLOCZ(s->bitstream_buffer, BITSTREAM_BUFFER_SIZE);
-
         /* cbp, ac_pred, pred_dir */
         CHECKED_ALLOCZ(s->cbp_table  , mb_array_size * sizeof(uint8_t))
         CHECKED_ALLOCZ(s->pred_dir_table, mb_array_size * sizeof(uint8_t))
@@ -849,6 +849,8 @@
     av_freep(&s->mbskip_table);
     av_freep(&s->prev_pict_types);
     av_freep(&s->bitstream_buffer);
+    s->allocated_bitstream_buffer_size=0;
+
     av_freep(&s->avctx->stats_out);
     av_freep(&s->ac_stats);
     av_freep(&s->error_status_table);
@@ -2314,6 +2316,11 @@
 
         stuffing_count= ff_vbv_update(s, s->frame_bits);
         if(stuffing_count){
+            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < stuffing_count + 50){
+                av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n");
+                return -1;
+            }
+
             switch(s->codec_id){
             case CODEC_ID_MPEG1VIDEO:
             case CODEC_ID_MPEG2VIDEO:
@@ -4555,16 +4562,16 @@
     int mb_x, mb_y, pdif = 0;
     int i, j;
     MpegEncContext best_s, backup_s;
-    uint8_t bit_buf[2][3000];
-    uint8_t bit_buf2[2][3000];
-    uint8_t bit_buf_tex[2][3000];
+    uint8_t bit_buf[2][MAX_MB_BYTES];
+    uint8_t bit_buf2[2][MAX_MB_BYTES];
+    uint8_t bit_buf_tex[2][MAX_MB_BYTES];
     PutBitContext pb[2], pb2[2], tex_pb[2];
 //printf("%d->%d\n", s->resync_mb_y, s->end_mb_y);
 
     for(i=0; i<2; i++){
-        init_put_bits(&pb    [i], bit_buf    [i], 3000);
-        init_put_bits(&pb2   [i], bit_buf2   [i], 3000);
-        init_put_bits(&tex_pb[i], bit_buf_tex[i], 3000);
+        init_put_bits(&pb    [i], bit_buf    [i], MAX_MB_BYTES);
+        init_put_bits(&pb2   [i], bit_buf2   [i], MAX_MB_BYTES);
+        init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES);
     }
 
     s->last_bits= put_bits_count(&s->pb);
@@ -4622,6 +4629,18 @@
             int dmin= INT_MAX;
             int dir;
 
+            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){
+                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                return -1;
+            }
+            if(s->data_partitioning){
+                if(   s->pb2   .buf_end - s->pb2   .buf - (put_bits_count(&s->    pb2)>>3) < MAX_MB_BYTES
+                   || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){
+                    av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                    return -1;
+                }
+            }
+
             s->mb_x = mb_x;
             s->mb_y = mb_y;  // moved into loop, can get changed by H.261
             ff_update_block_index(s);
--- a/mpegvideo.h	Tue Jan 11 08:16:04 2005 +0000
+++ b/mpegvideo.h	Wed Jan 12 00:16:25 2005 +0000
@@ -68,6 +68,8 @@
 #define SI_TYPE FF_SI_TYPE  ///< Switching Intra
 #define SP_TYPE FF_SP_TYPE  ///< Switching Predicted
 
+#define MAX_MB_BYTES (30*16*16*3/8 + 120)
+
 typedef struct Predictor{
     double coeff;
     double count;
@@ -599,9 +601,9 @@
     int divx_version;
     int divx_build;
     int divx_packed;
-#define BITSTREAM_BUFFER_SIZE 1024*256
     uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
     int bitstream_buffer_size;
+    int allocated_bitstream_buffer_size;
     
     int xvid_build;
     
--- a/png.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/png.c	Wed Jan 12 00:16:25 2005 +0000
@@ -140,6 +140,8 @@
 #endif
 static void *png_zalloc(void *opaque, unsigned int items, unsigned int size)
 {
+    if(items >= UINT_MAX / size)
+        return NULL;
     return av_malloc(items * size);
 }
 
@@ -522,6 +524,10 @@
                 goto fail;
             s->width = get32(&s->bytestream);
             s->height = get32(&s->bytestream);
+            if(avcodec_check_dimensions(avctx, s->width, s->height)){
+                s->width= s->height= 0;
+                goto fail;
+            }
             s->bit_depth = *s->bytestream++;
             s->color_type = *s->bytestream++;
             s->compression_type = *s->bytestream++;
@@ -727,7 +733,8 @@
         if (ret != Z_OK)
             return -1;
         if (s->zstream.avail_out == 0) {
-            png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, IOBUF_SIZE);
+            if(s->bytestream_end - s->bytestream > IOBUF_SIZE + 100)
+                png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, IOBUF_SIZE);
             s->zstream.avail_out = IOBUF_SIZE;
             s->zstream.next_out = s->buf;
         }
@@ -895,7 +902,7 @@
         ret = deflate(&s->zstream, Z_FINISH);
         if (ret == Z_OK || ret == Z_STREAM_END) {
             len = IOBUF_SIZE - s->zstream.avail_out;
-            if (len > 0) {
+            if (len > 0 && s->bytestream_end - s->bytestream > len + 100) {
                 png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, len);
             }
             s->zstream.avail_out = IOBUF_SIZE;
--- a/pnm.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/pnm.c	Wed Jan 12 00:16:25 2005 +0000
@@ -109,8 +109,9 @@
             }
         }
         /* check that all tags are present */
-        if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0')
+        if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || avcodec_check_dimensions(avctx, w, h))
             return -1;
+                   
         avctx->width = w;
         avctx->height = h;
         if (depth == 1) {
@@ -135,7 +136,7 @@
         return -1;
     pnm_get(s, buf1, sizeof(buf1));
     avctx->height = atoi(buf1);
-    if (avctx->height <= 0)
+    if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
         return -1;
     if (avctx->pix_fmt != PIX_FMT_MONOWHITE) {
         pnm_get(s, buf1, sizeof(buf1));
@@ -264,6 +265,11 @@
     int i, h, h1, c, n, linesize;
     uint8_t *ptr, *ptr1, *ptr2;
 
+    if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){
+        av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+        return -1;
+    }
+
     *p = *pict;
     p->pict_type= FF_I_TYPE;
     p->key_frame= 1;
@@ -338,6 +344,11 @@
     const char *tuple_type;
     uint8_t *ptr;
 
+    if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){
+        av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+        return -1;
+    }
+
     *p = *pict;
     p->pict_type= FF_I_TYPE;
     p->key_frame= 1;
--- a/ratecontrol.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/ratecontrol.c	Wed Jan 12 00:16:25 2005 +0000
@@ -74,6 +74,8 @@
             p= strchr(p+1, ';');
         }
         i+= s->max_b_frames;
+        if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry))
+            return -1;
         rcc->entry = (RateControlEntry*)av_mallocz(i*sizeof(RateControlEntry));
         rcc->num_entries= i;
         
--- a/snow.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/snow.c	Wed Jan 12 00:16:25 2005 +0000
@@ -1292,7 +1292,7 @@
     }
 }
 
-static void encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){
+static int encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){
     const int w= b->width;
     const int h= b->height;
     int x, y;
@@ -1347,6 +1347,10 @@
         put_symbol2(&s->c, b->state[1], run, 3);
         
         for(y=0; y<h; y++){
+            if(&s->c.bytestream_end - &s->c.bytestream < w*40){
+                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                return -1;
+            }
             for(x=0; x<w; x++){
                 int v, p=0;
                 int /*ll=0, */l=0, lt=0, t=0, rt=0;
@@ -1398,12 +1402,13 @@
             }
         }
     }
+    return 0;
 }
 
-static void encode_subband(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){    
+static int encode_subband(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){    
 //    encode_subband_qtree(s, b, src, parent, stride, orientation);
 //    encode_subband_z0run(s, b, src, parent, stride, orientation);
-    encode_subband_c0run(s, b, src, parent, stride, orientation);
+    return encode_subband_c0run(s, b, src, parent, stride, orientation);
 //    encode_subband_dzr(s, b, src, parent, stride, orientation);
 }
 
@@ -1918,6 +1923,10 @@
     int h= s->b_height;
 
     for(y=0; y<h; y++){
+        if(&s->c.bytestream_end - &s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit
+            av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+            return;
+        }
         for(x=0; x<w; x++){
             encode_q_branch(s, 0, x, y);
         }
--- a/svq1.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/svq1.c	Wed Jan 12 00:16:25 2005 +0000
@@ -1081,7 +1081,7 @@
 
 #ifdef CONFIG_ENCODERS
 
-static void svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane,
+static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane,
     int width, int height, int src_stride, int stride)
 {
     int x, y;
@@ -1188,6 +1188,11 @@
             uint8_t *ref= ref_plane + offset;
             int score[4]={0,0,0,0}, best;
             uint8_t temp[16*stride];
+            
+            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3000){ //FIXME check size
+                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                return -1;
+            }
 
             s->m.mb_x= x;
             ff_init_block_index(&s->m);
@@ -1280,6 +1285,7 @@
         }
         s->m.first_slice_line=0;
     }
+    return 0;
 }
 
 static int svq1_encode_init(AVCodecContext *avctx)
@@ -1341,10 +1347,11 @@
 
     svq1_write_header(s, p->pict_type);
     for(i=0; i<3; i++){
-        svq1_encode_plane(s, i,
+        if(svq1_encode_plane(s, i,
             s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i],
             s->frame_width / (i?4:1), s->frame_height / (i?4:1), 
-            s->picture.linesize[i], s->current_picture.linesize[i]);
+            s->picture.linesize[i], s->current_picture.linesize[i]) < 0)
+                return -1;
     }
 
 //    align_put_bits(&s->pb);
--- a/utils.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/utils.c	Wed Jan 12 00:16:25 2005 +0000
@@ -82,7 +82,7 @@
     if(min_size < *size) 
         return ptr;
     
-    *size= 17*min_size/16 + 32;
+    *size= FFMAX(17*min_size/16 + 32, min_size);
 
     return av_realloc(ptr, *size);
 }
@@ -101,6 +101,8 @@
 
     if(ptr){ 
         array_static =av_fast_realloc(array_static, &allocated_static, sizeof(void*)*(last_static+1));
+        if(!array_static)
+            return NULL;
         array_static[last_static++] = ptr;
     }
 
@@ -233,16 +235,27 @@
     *height= ALIGN(*height, h_align);
 }
 
+int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){
+    if((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/4)
+        return 0;
+    
+    av_log(av_log_ctx, AV_LOG_ERROR, "picture size invalid (%ux%u)\n", w, h);
+    return -1;
+}
+
 int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
     int i;
     int w= s->width;
     int h= s->height;
     InternalBuffer *buf;
     int *picture_number;
-    
+
     assert(pic->data[0]==NULL);
     assert(INTERNAL_BUFFER_SIZE > s->internal_buffer_count);
 
+    if(avcodec_check_dimensions(s,w,h))
+        return -1;
+
     if(s->internal_buffer==NULL){
         s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer));
     }
@@ -509,6 +522,11 @@
     else if(avctx->width && avctx->height)
         avcodec_set_dimensions(avctx, avctx->width, avctx->height);
 
+    if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)){
+        av_freep(&avctx->priv_data);
+        return -1;
+    }
+
     ret = avctx->codec->init(avctx);
     if (ret < 0) {
         av_freep(&avctx->priv_data);
@@ -520,6 +538,10 @@
 int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, 
                          const short *samples)
 {
+    if(buf_size < FF_MIN_BUFFER_SIZE && 0){
+        av_log(avctx, AV_LOG_ERROR, "buffer smaller then minimum size\n");
+        return -1;
+    }
     if((avctx->codec->capabilities & CODEC_CAP_DELAY) || samples){
         int ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples);
         avctx->frame_number++;
@@ -531,6 +553,12 @@
 int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, 
                          const AVFrame *pict)
 {
+    if(buf_size < FF_MIN_BUFFER_SIZE){
+        av_log(avctx, AV_LOG_ERROR, "buffer smaller then minimum size\n");
+        return -1;
+    }
+    if(avcodec_check_dimensions(avctx,avctx->width,avctx->height))
+        return -1;
     if((avctx->codec->capabilities & CODEC_CAP_DELAY) || pict){
         int ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict);
         avctx->frame_number++;
@@ -557,6 +585,8 @@
     int ret;
     
     *got_picture_ptr= 0;
+    if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height))
+        return -1;
     ret = avctx->codec->decode(avctx, picture, got_picture_ptr, 
                                buf, buf_size);
 
--- a/vp3.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/vp3.c	Wed Jan 12 00:16:25 2005 +0000
@@ -2093,6 +2093,9 @@
         upper_motion_limit = 7 * s->current_frame.linesize[2];
         lower_motion_limit = height * s->current_frame.linesize[2] + width - 8;
     }
+    
+    if((unsigned)stride > 2048)
+        return; //various tables are fixed size
 
     /* for each fragment row... */
     for (y = 0; y < height; y += 8) {
@@ -2681,6 +2684,11 @@
     s->width = get_bits(&gb, 16) << 4;
     s->height = get_bits(&gb, 16) << 4;
     
+    if(avcodec_check_dimensions(avctx, s->width, s->height)){
+        s->width= s->height= 0;
+        return -1;
+    }
+    
     skip_bits(&gb, 24); /* frame width */
     skip_bits(&gb, 24); /* frame height */
 
--- a/vqavideo.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/vqavideo.c	Wed Jan 12 00:16:25 2005 +0000
@@ -151,6 +151,10 @@
     s->vqa_version = vqa_header[0];
     s->width = LE_16(&vqa_header[6]);
     s->height = LE_16(&vqa_header[8]);
+    if(avcodec_check_dimensions(avctx, s->width, s->height)){
+        s->width= s->height= 0;
+        return -1;
+    }
     s->vector_width = vqa_header[10];
     s->vector_height = vqa_header[11];
     s->partial_count = s->partial_countdown = vqa_header[13];
--- a/xan.c	Tue Jan 11 08:16:04 2005 +0000
+++ b/xan.c	Wed Jan 12 00:16:25 2005 +0000
@@ -132,6 +132,9 @@
         v_b_table[i] = V_B * i;
     }
 
+    if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
+        return -1;
+    
     s->buffer1 = av_malloc(avctx->width * avctx->height);
     s->buffer2 = av_malloc(avctx->width * avctx->height);
     if (!s->buffer1 || !s->buffer2)