Vulnerability: The get_cox function in libavcodec/jpeg2000dec.c in FFmpeg before 2.1 does not properly validate the reduction factor, which allows remote attackers to cause a denial of service (out-of-bounds array access) or possibly have unspecified other impact via crafted JPEG2000 data.
Vulnerability ID: CVE-2013-7019
CWE: CWE-20
Severity score: 6.4
Project: https://github.com/FFmpeg/FFmpeg
Published: 2013-12-09
File: libavcodec/jpeg2000dec.c
Commit message: avcodec/jpeg2000dec: fix context consistency with too large lowres

Fixes out of array accesses
Fixes Ticket2898

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Commit author: Michael Niedermayer

Vulnerable version (before fix):
 static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)         return AVERROR_INVALIDDATA;     }      /* compute number of resolution levels to decode */     if (c->nreslevels < s->reduction_factor)         c->nreslevels2decode = 1;     else         c->nreslevels2decode = c->nreslevels - s->reduction_factor;      c->log2_cblk_width  = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width     c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height

Fixed version (after fix):
 static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)         return AVERROR_INVALIDDATA;     }      if (c->nreslevels <= s->reduction_factor) {         /* we are forced to update reduction_factor as its requested value is            not compatible with this bitstream, and as we might have used it            already in setup earlier we have to fail this frame until            reinitialization is implemented */         av_log(s->avctx, AV_LOG_ERROR, "reduction_factor too large for this bitstream, max is %d\n", c->nreslevels - 1);         s->reduction_factor = c->nreslevels - 1;         return AVERROR(EINVAL);     }      /* compute number of resolution levels to decode */     c->nreslevels2decode = c->nreslevels - s->reduction_factor;      c->log2_cblk_width  = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width     c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height

Patch:
patch: @@ -370,11 +370,18 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
         return AVERROR_INVALIDDATA;
     }
 
+    if (c->nreslevels <= s->reduction_factor) {
+        /* we are forced to update reduction_factor as its requested value is
+           not compatible with this bitstream, and as we might have used it
+           already in setup earlier we have to fail this frame until
+           reinitialization is implemented */
+        av_log(s->avctx, AV_LOG_ERROR, "reduction_factor too large for this bitstream, max is %d\n", c->nreslevels - 1);
+        s->reduction_factor = c->nreslevels - 1;
+        return AVERROR(EINVAL);
+    }
+
     /* compute number of resolution levels to decode */
-    if (c->nreslevels < s->reduction_factor)
-        c->nreslevels2decode = 1;
-    else
-        c->nreslevels2decode = c->nreslevels - s->reduction_factor;
+    c->nreslevels2decode = c->nreslevels - s->reduction_factor;
 
     c->log2_cblk_width  = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width
     c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height
path: libavcodec/jpeg2000dec.c