# HG changeset patch # User michael # Date 1230308941 0 # Node ID 0a0d7c4f2cf32388cf6f3ff7aa296651aae3e057 # Parent b7e5b6350969873836fbd2ac16fc5d7fa6c860ae Close gaping sechole. That is, a series of run=0 allows arbitrary data to be written over the end of the runs array. diff -r b7e5b6350969 -r 0a0d7c4f2cf3 faxcompr.c --- a/faxcompr.c Fri Dec 26 15:21:48 2008 +0000 +++ b/faxcompr.c Fri Dec 26 16:29:01 2008 +0000 @@ -123,7 +123,7 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, - int pix_left, int *runs) + int pix_left, int *runs, const int *runend) { int mode = 0, run = 0; unsigned int t; @@ -133,6 +133,10 @@ if(t < 64){ pix_left -= run; *runs++ = run; + if(runs >= runend){ + av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); + return -1; + } if(pix_left <= 0){ if(!pix_left) break; @@ -152,12 +156,14 @@ } static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, - int pix_left, int *runs, const int *ref) + int pix_left, int *runs, const int *runend, const int *ref) { int mode = 0, offs = 0, run = 0, saved_run = 0, t; int run_off = *ref++; int *run_start = runs; + runend--; // for the last written 0 + while(pix_left > 0){ int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); if(cmode == -1){ @@ -195,6 +201,10 @@ break; } *runs++ = run + saved_run; + if(runs >= runend){ + av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); + return -1; + } saved_run = 0; pix_left -= run; if(pix_left < 0){ @@ -220,6 +230,10 @@ } offs += run; *runs++ = run + saved_run; + if(runs >= runend){ + av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); + return -1; + } saved_run = 0; mode = !mode; } @@ -264,7 +278,7 @@ { int j; GetBitContext gb; - int *runs, *ref; + int *runs, *ref, *runend; int ret; runs = av_malloc((avctx->width + 2) * sizeof(runs[0])); @@ -274,8 +288,9 @@ ref[2] = 0; init_get_bits(&gb, src, srcsize*8); for(j = 0; j < height; j++){ + runend = runs + avctx->width + 2; if(compr == TIFF_G4){ - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, ref); + ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); if(ret < 0){ av_free(runs); av_free(ref); @@ -285,9 +300,9 @@ if(find_group3_syncmarker(&gb, srcsize*8) < 0) break; if(compr==TIFF_CCITT_RLE || get_bits1(&gb)) - ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs); + ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend); else - ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, ref); + ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref); } if(ret < 0){ put_line(dst, stride, avctx->width, ref);