[SCM] libav/experimental: various security fixes and precautionary checks

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Sun Jun 30 15:42:39 UTC 2013


The following commit has been merged in the experimental branch:
commit 0ecca7a49f8e254c12a3a1de048d738bfbb614c6
Author: Michael Niedermayer <michaelni at gmx.at>
Date:   Wed Jan 12 00:16:25 2005 +0000

    various security fixes and precautionary checks
    
    Originally committed as revision 3822 to svn://svn.ffmpeg.org/ffmpeg/trunk

diff --git a/cmdutils.c b/cmdutils.c
index 171fcfc..16067cb 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -35,10 +35,10 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int
                 printf("%s", msg);
                 first = 0;
             }
-            strcpy(buf, po->name);
+            pstrcpy(buf, sizeof(buf), po->name);
             if (po->flags & HAS_ARG) {
-                strcat(buf, " ");
-                strcat(buf, po->argname);
+                pstrcat(buf, sizeof(buf), " ");
+                pstrcat(buf, sizeof(buf), po->argname);
             }
             printf("-%-17s  %s\n", buf, po->help);
         }
diff --git a/ffmpeg.c b/ffmpeg.c
index 140efeb..eaebc01 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -1020,21 +1020,21 @@ static void print_report(AVFormatContext **output_files,
         os = output_files[ost->file_index];
         enc = &ost->st->codec;
         if (vid && enc->codec_type == CODEC_TYPE_VIDEO) {
-            sprintf(buf + strlen(buf), "q=%2.1f ",
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ",
                     enc->coded_frame->quality/(float)FF_QP2LAMBDA);
         }
         if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) {
             frame_number = ost->frame_number;
-            sprintf(buf + strlen(buf), "frame=%5d q=%2.1f ",
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d q=%2.1f ",
                     frame_number, enc->coded_frame ? enc->coded_frame->quality/(float)FF_QP2LAMBDA : 0);
             if(is_last_report)
-                sprintf(buf + strlen(buf), "L");
+                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
             if (enc->flags&CODEC_FLAG_PSNR){
                 int j;
                 double error, error_sum=0;
                 double scale, scale_sum=0;
                 char type[3]= {'Y','U','V'};
-                sprintf(buf + strlen(buf), "PSNR=");
+                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");
                 for(j=0; j<3; j++){
                     if(is_last_report){
                         error= enc->error[j];
@@ -1046,9 +1046,9 @@ static void print_report(AVFormatContext **output_files,
                     if(j) scale/=4;
                     error_sum += error;
                     scale_sum += scale;
-                    sprintf(buf + strlen(buf), "%c:%2.2f ", type[j], psnr(error/scale));
+                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error/scale));
                 }
-                sprintf(buf + strlen(buf), "*:%2.2f ", psnr(error_sum/scale_sum));
+                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum/scale_sum));
             }
             vid = 1;
         }
@@ -1063,12 +1063,12 @@ static void print_report(AVFormatContext **output_files,
     if (verbose || is_last_report) {
         bitrate = (double)(total_size * 8) / ti1 / 1000.0;
         
-        sprintf(buf + strlen(buf), 
+        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), 
             "size=%8.0fkB time=%0.1f bitrate=%6.1fkbits/s",
             (double)total_size / 1024, ti1, bitrate);
 
 	if (verbose > 1)
-	  sprintf(buf + strlen(buf), " dup=%d drop=%d",
+	  snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
 		  nb_frames_dup, nb_frames_drop);
         
         if (verbose >= 0)
@@ -3331,7 +3331,7 @@ static void opt_output_file(const char *filename)
 
     output_files[nb_output_files++] = oc;
 
-    strcpy(oc->filename, filename);
+    pstrcpy(oc->filename, sizeof(oc->filename), filename);
 
     /* check filename in case of an image number is expected */
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index 9f82fb1..5cc5f57 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -323,13 +323,19 @@ static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){
     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 @@ static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){
     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);
 
diff --git a/libavcodec/asv1.c b/libavcodec/asv1.c
index c369c0e..1a6b4a8 100644
--- a/libavcodec/asv1.c
+++ b/libavcodec/asv1.c
@@ -339,8 +339,13 @@ static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){
     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 @@ static inline void encode_mb(ASV1Context *a, DCTELEM block[6][64]){
         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){
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 61b0d3f..77f00cd 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -17,7 +17,7 @@ extern "C" {
 
 #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 @@ enum SampleFormat {
  */
 #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 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
 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);
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index 1e190a5..f548bff 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -931,7 +931,9 @@ static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
     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);
 
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index b9d2806..cc15d90 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -354,7 +354,7 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int
     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 @@ static inline void encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], i
     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 @@ static inline void encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], i
             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 @@ static int read_header(FFV1Context *f){
     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;
         }
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 99825ce..92cb8bd 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -176,7 +176,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
                 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;
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index afb9672..441721f 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -6115,7 +6115,7 @@ int flv_h263_decode_picture_header(MpegEncContext *s)
         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;
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 458307a..da94aed 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -724,9 +724,8 @@ retry:
     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 @@ retry:
         }
 
         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;
         }
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 5267b25..22106a9 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -5862,6 +5862,10 @@ static inline int decode_seq_parameter_set(H264Context *h){
     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);
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index e8a9ffa..5dec85c 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -65,13 +65,14 @@ typedef struct HYuvContext{
     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 @@ static int read_old_huffman_tables(HYuvContext *s){
 #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 store_table(HYuvContext *s, uint8_t *len, uint8_t *buf){
 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);
-    
-    width= s->width= avctx->width;
-    height= s->height= avctx->height;
+    common_init(avctx);
     
-    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 @@ static int encode_init(AVCodecContext *avctx)
             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 @@ static int encode_init(AVCodecContext *avctx)
 
     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 decode_gray_bitstream(HYuvContext *s, int count){
     }
 }
 
-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 @@ static void encode_422_bitstream(HYuvContext *s, int count){
             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 @@ static void encode_gray_bitstream(HYuvContext *s, int count){
             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 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
     /* 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 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
     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_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
 
 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);
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index 33c01a6..1ba723a 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -268,6 +268,9 @@ int avpicture_fill(AVPicture *picture, uint8_t *ptr,
     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 @@ int avpicture_fill(AVPicture *picture, uint8_t *ptr,
         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 @@ int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height,
     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 @@ int avpicture_alloc(AVPicture *picture,
     void *ptr;
 
     size = avpicture_get_size(pix_fmt, width, height);
+    if(size<0)
+        goto fail;
     ptr = av_malloc(size);
     if (!ptr)
         goto fail;
diff --git a/libavcodec/imgresample.c b/libavcodec/imgresample.c
index b4c5f36..3b74a82 100644
--- a/libavcodec/imgresample.c
+++ b/libavcodec/imgresample.c
@@ -561,6 +561,8 @@ ImgReSampleContext *img_resample_full_init(int owidth, int oheight,
     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;
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 7e4cf01..24e2160 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -196,6 +196,10 @@ static unsigned long iv_decode_frame(Indeo3DecodeContext *s,
   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;
diff --git a/libavcodec/mem.c b/libavcodec/mem.c
index 9eaa09e..6d0fadc 100644
--- a/libavcodec/mem.c
+++ b/libavcodec/mem.c
@@ -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_malloc(unsigned int size)
  */
 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;
diff --git a/libavcodec/mjpeg.c b/libavcodec/mjpeg.c
index daa28d3..b09492d 100644
--- a/libavcodec/mjpeg.c
+++ b/libavcodec/mjpeg.c
@@ -659,11 +659,11 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in
     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 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in
             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 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in
         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 @@ static int mjpeg_decode_sof(MJpegDecodeContext *s)
     }
     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 decode_block(MJpegDecodeContext *s, DCTELEM *block,
 
 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);
     }
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 55c8601..ffb7e0f 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -619,6 +619,9 @@ int MPV_common_init(MpegEncContext *s)
         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 @@ int MPV_common_init(MpegEncContext *s)
         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 @@ void MPV_common_end(MpegEncContext *s)
     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 @@ int MPV_encode_picture(AVCodecContext *avctx,
 
         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 @@ static int encode_thread(AVCodecContext *c, void *arg){
     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 @@ static int encode_thread(AVCodecContext *c, void *arg){
             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);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 4968295..920d8c7 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -68,6 +68,8 @@ enum OutputFormat {
 #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 @@ typedef struct MpegEncContext {
     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;
     
diff --git a/libavcodec/png.c b/libavcodec/png.c
index 11faa86..2945d0c 100644
--- a/libavcodec/png.c
+++ b/libavcodec/png.c
@@ -140,6 +140,8 @@ static int png_probe(AVProbeData *pd)
 #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 @@ static int decode_frame(AVCodecContext *avctx,
                 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 @@ static int png_write_row(PNGContext *s, const uint8_t *data, int size)
         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 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
         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;
diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c
index 1bfbf17..51134ce 100644
--- a/libavcodec/pnm.c
+++ b/libavcodec/pnm.c
@@ -109,8 +109,9 @@ static int pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){
             }
         }
         /* 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 @@ static int pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){
         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 @@ static int pnm_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int bu
     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 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int bu
     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;
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 473645d..a304f48 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -74,6 +74,8 @@ int ff_rate_control_init(MpegEncContext *s)
             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;
         
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index c9d47a8..a84ec7e 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -1292,7 +1292,7 @@ void ff_spatial_idwt(DWTELEM *buffer, int width, int height, int stride, int typ
     }
 }
 
-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 @@ static void encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTEL
         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 @@ static void encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTEL
             }
         }
     }
+    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 @@ static void encode_blocks(SnowContext *s){
     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);
         }
diff --git a/libavcodec/svq1.c b/libavcodec/svq1.c
index 4c27fb8..c719a8e 100644
--- a/libavcodec/svq1.c
+++ b/libavcodec/svq1.c
@@ -1081,7 +1081,7 @@ static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *dec
 
 #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 @@ static void svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plan
             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 @@ static void svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plan
         }
         s->m.first_slice_line=0;
     }
+    return 0;
 }
 
 static int svq1_encode_init(AVCodecContext *avctx)
@@ -1341,10 +1347,11 @@ static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
 
     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);
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index aa042c7..4111a63 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -82,7 +82,7 @@ void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size)
     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 @@ void *av_mallocz_static(unsigned int size)
 
     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 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){
     *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 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec)
     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_open(AVCodecContext *avctx, AVCodec *codec)
 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_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size,
 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 avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
     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);
 
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 4c7976c..8b90438 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -2093,6 +2093,9 @@ static void render_fragments(Vp3DecodeContext *s,
         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 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext gb)
     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 */
 
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index ea86fb1..fb0871e 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -151,6 +151,10 @@ static int vqa_decode_init(AVCodecContext *avctx)
     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];
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index f98a06b..377a71e 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -132,6 +132,9 @@ static int xan_decode_init(AVCodecContext *avctx)
         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)
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index 39e1e87..73d6377 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -279,7 +279,7 @@ static int fourxm_read_packet(AVFormatContext *s,
 
             /* allocate 8 more bytes than 'size' to account for fourcc
              * and size */
-            if (av_new_packet(pkt, size + 8))
+            if (size + 8 < size || av_new_packet(pkt, size + 8))
                 return AVERROR_IO;
             pkt->stream_index = fourxm->video_stream_index;
             pkt->pts = fourxm->video_pts;
diff --git a/libavformat/asf.c b/libavformat/asf.c
index cde3054..8450b53 100644
--- a/libavformat/asf.c
+++ b/libavformat/asf.c
@@ -333,7 +333,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                         {
                                 value = (char *)av_mallocz(value_len);
                                 get_str16_nolen(pb, value_len, value, value_len);
-                                if (strcmp(name,"WM/AlbumTitle")==0) { strcpy(s->album, value); }
+                                if (strcmp(name,"WM/AlbumTitle")==0) { pstrcpy(s->album, sizeof(s->album), value); }
                                 av_free(value);
                         }
                         if ((value_type >= 2) || (value_type <= 5)) // boolean or DWORD or QWORD or WORD
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index bb55254..7db4f15 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -350,6 +350,9 @@ int get_buffer(ByteIOContext *s, unsigned char *buf, int size)
 int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size)
 {
     int len;
+    
+    if(size<0)
+        return -1;
 
     len = s->buf_end - s->buf_ptr;
     if (len == 0) {
diff --git a/libavformat/flic.c b/libavformat/flic.c
index 65b7b9f..7fc3b9a 100644
--- a/libavformat/flic.c
+++ b/libavformat/flic.c
@@ -171,7 +171,7 @@ static int flic_read_packet(AVFormatContext *s,
         size = LE_32(&preamble[0]);
         magic = LE_16(&preamble[4]);
 
-        if ((magic == FLIC_CHUNK_MAGIC_1) || (magic == FLIC_CHUNK_MAGIC_2)) {
+        if (((magic == FLIC_CHUNK_MAGIC_1) || (magic == FLIC_CHUNK_MAGIC_2)) && size > FLIC_PREAMBLE_SIZE) {
             if (av_new_packet(pkt, size)) {
                 ret = AVERROR_IO;
                 break;
diff --git a/libavformat/idroq.c b/libavformat/idroq.c
index 5380f81..13553ed 100644
--- a/libavformat/idroq.c
+++ b/libavformat/idroq.c
@@ -196,6 +196,8 @@ static int roq_read_packet(AVFormatContext *s,
 
         chunk_type = LE_16(&preamble[0]);
         chunk_size = LE_32(&preamble[2]);
+        if(chunk_size > INT_MAX)
+            return AVERROR_INVALIDDATA;
 
         switch (chunk_type) {
 
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
index 3f752a1..d984a3b 100644
--- a/libavformat/segafilm.c
+++ b/libavformat/segafilm.c
@@ -231,6 +231,8 @@ static int film_read_packet(AVFormatContext *s,
         (film->video_type == CODEC_ID_CINEPAK)) {
         if (av_new_packet(pkt, sample->sample_size - film->cvid_extra_bytes))
             return AVERROR_NOMEM;
+        if(pkt->size < 10)
+            return -1;
         ret = get_buffer(pb, pkt->data, 10);
         /* skip the non-spec CVID bytes */
         url_fseek(pb, film->cvid_extra_bytes, SEEK_CUR);
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 8366b35..44f5e76 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -57,7 +57,7 @@ int match_ext(const char *filename, const char *extensions)
         p = extensions;
         for(;;) {
             q = ext1;
-            while (*p != '\0' && *p != ',') 
+            while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1) 
                 *q++ = *p++;
             *q = '\0';
             if (!strcasecmp(ext1, ext)) 
diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c
index b5f5c35..6f9fedd 100644
--- a/libavformat/wc3movie.c
+++ b/libavformat/wc3movie.c
@@ -169,14 +169,16 @@ static int wc3_read_header(AVFormatContext *s,
             if ((ret = get_buffer(pb, preamble, 4)) != 4)
                 return AVERROR_IO;
             wc3->palette_count = LE_32(&preamble[0]);
-            if((unsigned)wc3->palette_count >= UINT_MAX / PALETTE_SIZE)
+            if((unsigned)wc3->palette_count >= UINT_MAX / PALETTE_SIZE){
+                wc3->palette_count= 0;
                 return -1;
+            }
             wc3->palettes = av_malloc(wc3->palette_count * PALETTE_SIZE);
             break;
 
         case BNAM_TAG:
             /* load up the name */
-            if (size < 512)
+            if ((unsigned)size < 512)
                 bytes_to_read = size;
             else
                 bytes_to_read = 512;
@@ -195,7 +197,7 @@ static int wc3_read_header(AVFormatContext *s,
 
         case PALT_TAG:
             /* one of several palettes */
-            if (current_palette >= wc3->palette_count)
+            if ((unsigned)current_palette >= wc3->palette_count)
                 return AVERROR_INVALIDDATA;
             if ((ret = get_buffer(pb, 
                 &wc3->palettes[current_palette * PALETTE_SIZE], 
@@ -331,7 +333,7 @@ static int wc3_read_packet(AVFormatContext *s,
 #if 0
             url_fseek(pb, size, SEEK_CUR);
 #else
-            if ((ret = get_buffer(pb, text, size)) != size)
+            if ((unsigned)size > sizeof(text) || (ret = get_buffer(pb, text, size)) != size)
                 ret = AVERROR_IO;
             else {
                 int i = 0;

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list